From c07f3e60c2d455e36ba4ac339d4283d32bbc3814 Mon Sep 17 00:00:00 2001 From: Erik Romijn Date: Mon, 21 Apr 2014 12:32:25 +0200 Subject: [PATCH] Added information on resolved security issues to release notes. --- docs/releases/1.4.11.txt | 108 ++++++++++++++++++++++++++++++++++++-- docs/releases/1.5.6.txt | 110 +++++++++++++++++++++++++++++++++++++-- docs/releases/1.6.3.txt | 107 +++++++++++++++++++++++++++++++++++-- 3 files changed, 316 insertions(+), 9 deletions(-) diff --git a/docs/releases/1.4.11.txt b/docs/releases/1.4.11.txt index b42b20aa7b0..24194540d57 100644 --- a/docs/releases/1.4.11.txt +++ b/docs/releases/1.4.11.txt @@ -2,7 +2,109 @@ Django 1.4.11 release notes =========================== -*Under development* +*April 21, 2014* -Django's vendored version of six, :mod:`django.utils.six`, has been upgraded to -the latest release (1.6.1). +Django 1.4.11 fixes three security issues in 1.4.10. Additionally, +Django's vendored version of six, :mod:`django.utils.six`, has been +upgraded to the latest release (1.6.1). + +Unexpected code execution using ``reverse()`` +============================================= + +Django's URL handling is based on a mapping of regex patterns +(representing the URLs) to callable views, and Django's own processing +consists of matching a requested URL against those patterns to +determine the appropriate view to invoke. + +Django also provides a convenience function -- +:func:`~django.core.urlresolvers.reverse` -- which performs this process +in the opposite direction. The ``reverse()`` function takes +information about a view and returns a URL which would invoke that +view. Use of ``reverse()`` is encouraged for application developers, +as the output of ``reverse()`` is always based on the current URL +patterns, meaning developers do not need to change other code when +making changes to URLs. + +One argument signature for ``reverse()`` is to pass a dotted Python +path to the desired view. In this situation, Django will import the +module indicated by that dotted path as part of generating the +resulting URL. If such a module has import-time side effects, those +side effects will occur. + +Thus it is possible for an attacker to cause unexpected code +execution, given the following conditions: + +1. One or more views are present which construct a URL based on user + input (commonly, a "next" parameter in a querystring indicating + where to redirect upon successful completion of an action). + +2. One or more modules are known to an attacker to exist on the + server's Python import path, which perform code execution with side + effects on importing. + +To remedy this, ``reverse()`` will now only accept and import dotted +paths based on the view-containing modules listed in the project's :doc:`URL +pattern configuration `, so as to ensure that only modules +the developer intended to be imported in this fashion can or will be imported. + +Caching of anonymous pages could reveal CSRF token +================================================== + +Django includes both a :doc:`caching framework ` and a system +for :doc:`preventing cross-site request forgery (CSRF) attacks +`. The CSRF-protection system is based on a random nonce +sent to the client in a cookie which must be sent by the client on future +requests and, in forms, a hidden value which must be submitted back with the +form. + +The caching framework includes an option to cache responses to +anonymous (i.e., unauthenticated) clients. + +When the first anonymous request to a given page is by a client which +did not have a CSRF cookie, the cache framework will also cache the +CSRF cookie and serve the same nonce to other anonymous clients who +do not have a CSRF cookie. This can allow an attacker to obtain a +valid CSRF cookie value and perform attacks which bypass the check for +the cookie. + +To remedy this, the caching framework will no longer cache such +responses. The heuristic for this will be: + +1. If the incoming request did not submit any cookies, and + +2. If the response did send one or more cookies, and + +3. If the ``Vary: Cookie`` header is set on the response, then the + response will not be cached. + +MySQL typecasting +================= + +The MySQL database is known to "typecast" on certain queries; for +example, when querying a table which contains string values, but using +a query which filters based on an integer value, MySQL will first +silently coerce the strings to integers and return a result based on that. + +If a query is performed without first converting values to the +appropriate type, this can produce unexpected results, similar to what +would occur if the query itself had been manipulated. + +Django's model field classes are aware of their own types and most +such classes perform explicit conversion of query arguments to the +correct database-level type before querying. However, three model +field classes did not correctly convert their arguments: + +* :class:`~django.db.models.FilePathField` +* :class:`~django.db.models.GenericIPAddressField` +* :class:`~django.db.models.IPAddressField` + +These three fields have been updated to convert their arguments to the +correct types before querying. + +Additionally, developers of custom model fields are now warned via +documentation to ensure their custom field classes will perform +appropriate type conversions, and users of the :meth:`raw() +` and :meth:`extra() +` query methods -- which allow the +developer to supply raw SQL or SQL fragments -- will be advised to ensure they +perform appropriate manual type conversions prior to executing queries. diff --git a/docs/releases/1.5.6.txt b/docs/releases/1.5.6.txt index fb55820f201..1410d143c86 100644 --- a/docs/releases/1.5.6.txt +++ b/docs/releases/1.5.6.txt @@ -2,10 +2,111 @@ Django 1.5.6 release notes ========================== -*Under development* +*April 21, 2014* -Django's vendored version of six, :mod:`django.utils.six`, has been upgraded to -the latest release (1.6.1). +Django 1.5.6 fixes several bugs in 1.5.5, including three security +issues. + +Unexpected code execution using ``reverse()`` +============================================= + +Django's URL handling is based on a mapping of regex patterns +(representing the URLs) to callable views, and Django's own processing +consists of matching a requested URL against those patterns to +determine the appropriate view to invoke. + +Django also provides a convenience function -- +:func:`~django.core.urlresolvers.reverse` -- which performs this process +in the opposite direction. The ``reverse()`` function takes +information about a view and returns a URL which would invoke that +view. Use of ``reverse()`` is encouraged for application developers, +as the output of ``reverse()`` is always based on the current URL +patterns, meaning developers do not need to change other code when +making changes to URLs. + +One argument signature for ``reverse()`` is to pass a dotted Python +path to the desired view. In this situation, Django will import the +module indicated by that dotted path as part of generating the +resulting URL. If such a module has import-time side effects, those +side effects will occur. + +Thus it is possible for an attacker to cause unexpected code +execution, given the following conditions: + +1. One or more views are present which construct a URL based on user + input (commonly, a "next" parameter in a querystring indicating + where to redirect upon successful completion of an action). + +2. One or more modules are known to an attacker to exist on the + server's Python import path, which perform code execution with side + effects on importing. + +To remedy this, ``reverse()`` will now only accept and import dotted +paths based on the view-containing modules listed in the project's :doc:`URL +pattern configuration `, so as to ensure that only modules +the developer intended to be imported in this fashion can or will be imported. + +Caching of anonymous pages could reveal CSRF token +================================================== + +Django includes both a :doc:`caching framework ` and a system +for :doc:`preventing cross-site request forgery (CSRF) attacks +`. The CSRF-protection system is based on a random nonce +sent to the client in a cookie which must be sent by the client on future +requests and, in forms, a hidden value which must be submitted back with the +form. + +The caching framework includes an option to cache responses to +anonymous (i.e., unauthenticated) clients. + +When the first anonymous request to a given page is by a client which +did not have a CSRF cookie, the cache framework will also cache the +CSRF cookie and serve the same nonce to other anonymous clients who +do not have a CSRF cookie. This can allow an attacker to obtain a +valid CSRF cookie value and perform attacks which bypass the check for +the cookie. + +To remedy this, the caching framework will no longer cache such +responses. The heuristic for this will be: + +1. If the incoming request did not submit any cookies, and + +2. If the response did send one or more cookies, and + +3. If the ``Vary: Cookie`` header is set on the response, then the + response will not be cached. + +MySQL typecasting +================= + +The MySQL database is known to "typecast" on certain queries; for +example, when querying a table which contains string values, but using +a query which filters based on an integer value, MySQL will first +silently coerce the strings to integers and return a result based on that. + +If a query is performed without first converting values to the +appropriate type, this can produce unexpected results, similar to what +would occur if the query itself had been manipulated. + +Django's model field classes are aware of their own types and most +such classes perform explicit conversion of query arguments to the +correct database-level type before querying. However, three model +field classes did not correctly convert their arguments: + +* :class:`~django.db.models.FilePathField` +* :class:`~django.db.models.GenericIPAddressField` +* :class:`~django.db.models.IPAddressField` + +These three fields have been updated to convert their arguments to the +correct types before querying. + +Additionally, developers of custom model fields are now warned via +documentation to ensure their custom field classes will perform +appropriate type conversions, and users of the :meth:`raw() +` and :meth:`extra() +` query methods -- which allow the +developer to supply raw SQL or SQL fragments -- will be advised to ensure they +perform appropriate manual type conversions prior to executing queries. Bugfixes ======== @@ -13,3 +114,6 @@ Bugfixes * Fixed :class:`~django.contrib.auth.backends.ModelBackend` raising ``UnboundLocalError`` if :func:`~django.contrib.auth.get_user_model` raised an error (#21439). + +Additionally, Django's vendored version of six, :mod:`django.utils.six`, +has been upgraded to the latest release (1.6.1). diff --git a/docs/releases/1.6.3.txt b/docs/releases/1.6.3.txt index 12d1aee8fae..d06a9d44df8 100644 --- a/docs/releases/1.6.3.txt +++ b/docs/releases/1.6.3.txt @@ -2,10 +2,111 @@ Django 1.6.3 release notes ========================== -*Under development* +*April 21, 2014* -This is Django 1.6.3, a bugfix release for Django 1.6. Django 1.6.3 fixes -several bugs in 1.6.2 and makes one backwards-incompatible change: +Django 1.6.3 fixes several bugs in 1.6.2, including three security issues, +and makes one backwards-incompatible change: + +Unexpected code execution using ``reverse()`` +============================================= + +Django's URL handling is based on a mapping of regex patterns +(representing the URLs) to callable views, and Django's own processing +consists of matching a requested URL against those patterns to +determine the appropriate view to invoke. + +Django also provides a convenience function -- +:func:`~django.core.urlresolvers.reverse` -- which performs this process +in the opposite direction. The ``reverse()`` function takes +information about a view and returns a URL which would invoke that +view. Use of ``reverse()`` is encouraged for application developers, +as the output of ``reverse()`` is always based on the current URL +patterns, meaning developers do not need to change other code when +making changes to URLs. + +One argument signature for ``reverse()`` is to pass a dotted Python +path to the desired view. In this situation, Django will import the +module indicated by that dotted path as part of generating the +resulting URL. If such a module has import-time side effects, those +side effects will occur. + +Thus it is possible for an attacker to cause unexpected code +execution, given the following conditions: + +1. One or more views are present which construct a URL based on user + input (commonly, a "next" parameter in a querystring indicating + where to redirect upon successful completion of an action). + +2. One or more modules are known to an attacker to exist on the + server's Python import path, which perform code execution with side + effects on importing. + +To remedy this, ``reverse()`` will now only accept and import dotted +paths based on the view-containing modules listed in the project's :doc:`URL +pattern configuration `, so as to ensure that only modules +the developer intended to be imported in this fashion can or will be imported. + +Caching of anonymous pages could reveal CSRF token +================================================== + +Django includes both a :doc:`caching framework ` and a system +for :doc:`preventing cross-site request forgery (CSRF) attacks +`. The CSRF-protection system is based on a random nonce +sent to the client in a cookie which must be sent by the client on future +requests and, in forms, a hidden value which must be submitted back with the +form. + +The caching framework includes an option to cache responses to +anonymous (i.e., unauthenticated) clients. + +When the first anonymous request to a given page is by a client which +did not have a CSRF cookie, the cache framework will also cache the +CSRF cookie and serve the same nonce to other anonymous clients who +do not have a CSRF cookie. This can allow an attacker to obtain a +valid CSRF cookie value and perform attacks which bypass the check for +the cookie. + +To remedy this, the caching framework will no longer cache such +responses. The heuristic for this will be: + +1. If the incoming request did not submit any cookies, and + +2. If the response did send one or more cookies, and + +3. If the ``Vary: Cookie`` header is set on the response, then the + response will not be cached. + +MySQL typecasting +================= + +The MySQL database is known to "typecast" on certain queries; for +example, when querying a table which contains string values, but using +a query which filters based on an integer value, MySQL will first +silently coerce the strings to integers and return a result based on that. + +If a query is performed without first converting values to the +appropriate type, this can produce unexpected results, similar to what +would occur if the query itself had been manipulated. + +Django's model field classes are aware of their own types and most +such classes perform explicit conversion of query arguments to the +correct database-level type before querying. However, three model +field classes did not correctly convert their arguments: + +* :class:`~django.db.models.FilePathField` +* :class:`~django.db.models.GenericIPAddressField` +* :class:`~django.db.models.IPAddressField` + +These three fields have been updated to convert their arguments to the +correct types before querying. + +Additionally, developers of custom model fields are now warned via +documentation to ensure their custom field classes will perform +appropriate type conversions, and users of the :meth:`raw() +` and :meth:`extra() +` query methods -- which allow the +developer to supply raw SQL or SQL fragments -- will be advised to ensure they +perform appropriate manual type conversions prior to executing queries. ``select_for_update()`` requires a transaction ==============================================