1. ==========================
    
  2. Django 1.6.3 release notes
    
  3. ==========================
    
  4. 
    
  5. *April 21, 2014*
    
  6. 
    
  7. Django 1.6.3 fixes several bugs in 1.6.2, including three security issues,
    
  8. and makes one backwards-incompatible change:
    
  9. 
    
  10. Unexpected code execution using ``reverse()``
    
  11. =============================================
    
  12. 
    
  13. Django's URL handling is based on a mapping of regex patterns
    
  14. (representing the URLs) to callable views, and Django's own processing
    
  15. consists of matching a requested URL against those patterns to
    
  16. determine the appropriate view to invoke.
    
  17. 
    
  18. Django also provides a convenience function -- ``reverse()`` -- which performs
    
  19. this process in the opposite direction. The ``reverse()`` function takes
    
  20. information about a view and returns a URL which would invoke that view. Use
    
  21. of ``reverse()`` is encouraged for application developers, as the output of
    
  22. ``reverse()`` is always based on the current URL patterns, meaning developers
    
  23. do not need to change other code when making changes to URLs.
    
  24. 
    
  25. One argument signature for ``reverse()`` is to pass a dotted Python
    
  26. path to the desired view. In this situation, Django will import the
    
  27. module indicated by that dotted path as part of generating the
    
  28. resulting URL. If such a module has import-time side effects, those
    
  29. side effects will occur.
    
  30. 
    
  31. Thus it is possible for an attacker to cause unexpected code
    
  32. execution, given the following conditions:
    
  33. 
    
  34. 1. One or more views are present which construct a URL based on user
    
  35.    input (commonly, a "next" parameter in a querystring indicating
    
  36.    where to redirect upon successful completion of an action).
    
  37. 
    
  38. 2. One or more modules are known to an attacker to exist on the
    
  39.    server's Python import path, which perform code execution with side
    
  40.    effects on importing.
    
  41. 
    
  42. To remedy this, ``reverse()`` will now only accept and import dotted
    
  43. paths based on the view-containing modules listed in the project's :doc:`URL
    
  44. pattern configuration </topics/http/urls>`, so as to ensure that only modules
    
  45. the developer intended to be imported in this fashion can or will be imported.
    
  46. 
    
  47. Caching of anonymous pages could reveal CSRF token
    
  48. ==================================================
    
  49. 
    
  50. Django includes both a :doc:`caching framework </topics/cache>` and a system
    
  51. for :doc:`preventing cross-site request forgery (CSRF) attacks
    
  52. </ref/csrf/>`. The CSRF-protection system is based on a random nonce
    
  53. sent to the client in a cookie which must be sent by the client on future
    
  54. requests and, in forms, a hidden value which must be submitted back with the
    
  55. form.
    
  56. 
    
  57. The caching framework includes an option to cache responses to
    
  58. anonymous (i.e., unauthenticated) clients.
    
  59. 
    
  60. When the first anonymous request to a given page is by a client which
    
  61. did not have a CSRF cookie, the cache framework will also cache the
    
  62. CSRF cookie and serve the same nonce to other anonymous clients who
    
  63. do not have a CSRF cookie. This can allow an attacker to obtain a
    
  64. valid CSRF cookie value and perform attacks which bypass the check for
    
  65. the cookie.
    
  66. 
    
  67. To remedy this, the caching framework will no longer cache such
    
  68. responses. The heuristic for this will be:
    
  69. 
    
  70. 1. If the incoming request did not submit any cookies, and
    
  71. 
    
  72. 2. If the response did send one or more cookies, and
    
  73. 
    
  74. 3. If the ``Vary: Cookie`` header is set on the response, then the
    
  75.    response will not be cached.
    
  76. 
    
  77. MySQL typecasting
    
  78. =================
    
  79. 
    
  80. The MySQL database is known to "typecast" on certain queries; for
    
  81. example, when querying a table which contains string values, but using
    
  82. a query which filters based on an integer value, MySQL will first
    
  83. silently coerce the strings to integers and return a result based on that.
    
  84. 
    
  85. If a query is performed without first converting values to the
    
  86. appropriate type, this can produce unexpected results, similar to what
    
  87. would occur if the query itself had been manipulated.
    
  88. 
    
  89. Django's model field classes are aware of their own types and most
    
  90. such classes perform explicit conversion of query arguments to the
    
  91. correct database-level type before querying. However, three model
    
  92. field classes did not correctly convert their arguments:
    
  93. 
    
  94. * :class:`~django.db.models.FilePathField`
    
  95. * :class:`~django.db.models.GenericIPAddressField`
    
  96. * ``IPAddressField``
    
  97. 
    
  98. These three fields have been updated to convert their arguments to the
    
  99. correct types before querying.
    
  100. 
    
  101. Additionally, developers of custom model fields are now warned via
    
  102. documentation to ensure their custom field classes will perform
    
  103. appropriate type conversions, and users of the :meth:`raw()
    
  104. <django.db.models.query.QuerySet.raw>` and :meth:`extra()
    
  105. <django.db.models.query.QuerySet.extra>` query methods -- which allow the
    
  106. developer to supply raw SQL or SQL fragments -- will be advised to ensure they
    
  107. perform appropriate manual type conversions prior to executing queries.
    
  108. 
    
  109. ``select_for_update()`` requires a transaction
    
  110. ==============================================
    
  111. 
    
  112. Historically, queries that use
    
  113. :meth:`~django.db.models.query.QuerySet.select_for_update()` could be
    
  114. executed in autocommit mode, outside of a transaction. Before Django
    
  115. 1.6, Django's automatic transactions mode allowed this to be used to
    
  116. lock records until the next write operation. Django 1.6 introduced
    
  117. database-level autocommit; since then, execution in such a context
    
  118. voids the effect of ``select_for_update()``. It is, therefore, assumed
    
  119. now to be an error and raises an exception.
    
  120. 
    
  121. This change was made because such errors can be caused by including an
    
  122. app which expects global transactions (e.g. :setting:`ATOMIC_REQUESTS
    
  123. <DATABASE-ATOMIC_REQUESTS>` set to ``True``), or Django's old autocommit
    
  124. behavior, in a project which runs without them; and further, such
    
  125. errors may manifest as data-corruption bugs.
    
  126. 
    
  127. This change may cause test failures if you use ``select_for_update()``
    
  128. in a test class which is a subclass of
    
  129. :class:`~django.test.TransactionTestCase` rather than
    
  130. :class:`~django.test.TestCase`.
    
  131. 
    
  132. Other bugfixes and changes
    
  133. ==========================
    
  134. 
    
  135. * Content retrieved from the GeoIP library is now properly decoded from its
    
  136.   default ``iso-8859-1`` encoding
    
  137.   (:ticket:`21996`).
    
  138. 
    
  139. * Fixed ``AttributeError`` when using
    
  140.   :meth:`~django.db.models.query.QuerySet.bulk_create` with ``ForeignObject``
    
  141.   (:ticket:`21566`).
    
  142. 
    
  143. * Fixed crash of ``QuerySet``\s that use ``F() + timedelta()`` when their query
    
  144.   was compiled more once
    
  145.   (:ticket:`21643`).
    
  146. 
    
  147. * Prevented custom ``widget`` class attribute of
    
  148.   :class:`~django.forms.IntegerField` subclasses from being overwritten by the
    
  149.   code in their ``__init__`` method
    
  150.   (:ticket:`22245`).
    
  151. 
    
  152. * Improved :func:`~django.utils.html.strip_tags` accuracy (but it still cannot
    
  153.   guarantee an HTML-safe result, as stated in the documentation).
    
  154. 
    
  155. * Fixed a regression in the :mod:`django.contrib.gis` SQL compiler for
    
  156.   non-concrete fields (:ticket:`22250`).
    
  157. 
    
  158. * Fixed :attr:`ModelAdmin.preserve_filters
    
  159.   <django.contrib.admin.ModelAdmin.preserve_filters>` when running a site with
    
  160.   a URL prefix (:ticket:`21795`).
    
  161. 
    
  162. * Fixed a crash in the ``find_command`` management utility when the ``PATH``
    
  163.   environment variable wasn't set
    
  164.   (:ticket:`22256`).
    
  165. 
    
  166. * Fixed :djadmin:`changepassword` on Windows
    
  167.   (:ticket:`22364`).
    
  168. 
    
  169. * Avoided shadowing deadlock exceptions on MySQL
    
  170.   (:ticket:`22291`).
    
  171. 
    
  172. * Wrapped database exceptions in ``_set_autocommit``
    
  173.   (:ticket:`22321`).
    
  174. 
    
  175. * Fixed atomicity when closing a database connection or when the database server
    
  176.   disconnects (:ticket:`21239` and :ticket:`21202`)
    
  177. 
    
  178. * Fixed regression in ``prefetch_related`` that caused the related objects
    
  179.   query to include an unnecessary join
    
  180.   (:ticket:`21760`).
    
  181. 
    
  182. Additionally, Django's vendored version of six, ``django.utils.six`` has been
    
  183. upgraded to the latest release (1.6.1).