Fixed #15253, #15259 -- Added 1.1.4 release notes, added a section on CSRF changes to the 1.3 release notes, and corrected the example in the 1.2.5 release notes. Thanks to Gary Wilson and Mark Hellewell for the reports.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15482 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2011-02-10 09:27:38 +00:00
parent 1ca9ceda59
commit f913fab6be
4 changed files with 174 additions and 7 deletions

78
docs/releases/1.1.4.txt Normal file
View File

@ -0,0 +1,78 @@
==========================
Django 1.1.4 release notes
==========================
Welcome to Django 1.1.4!
This is the fourth "bugfix" release in the Django 1.1 series,
improving the stability and performance of the Django 1.1 codebase.
With one exception, Django 1.1.4 maintains backwards compatibility
with Django 1.1.3, but contain a number of fixes and other
improvements. Django 1.1.4 is a recommended upgrade for any
development or deployment currently using or targeting Django 1.1.
For full details on the new features, backwards incompatibilities, and
deprecated features in the 1.1 branch, see the :doc:`/releases/1.1`.
Backwards-incompatible changes in 1.1.4
=======================================
CSRF exception for AJAX requests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Django includes a CSRF-protection mechanism, which makes use of a
token inserted into outgoing forms. Middleware then checks for the
token's presence on form submission, and validates it.
Prior to Django 1.2.5, our CSRF protection made an exception for AJAX
requests, on the following basis:
* Many AJAX toolkits add an X-Requested-With header when using
XMLHttpRequest.
* Browsers have strict same-origin policies regarding
XMLHttpRequest.
* In the context of a browser, the only way that a custom header
of this nature can be added is with XMLHttpRequest.
Therefore, for ease of use, we did not apply CSRF checks to requests
that appeared to be AJAX on the basis of the X-Requested-With header.
The Ruby on Rails web framework had a similar exemption.
Recently, engineers at Google made members of the Ruby on Rails
development team aware of a combination of browser plugins and
redirects which can allow an attacker to provide custom HTTP headers
on a request to any website. This can allow a forged request to appear
to be an AJAX request, thereby defeating CSRF protection which trusts
the same-origin nature of AJAX requests.
Michael Koziarski of the Rails team brought this to our attention, and
we were able to produce a proof-of-concept demonstrating the same
vulnerability in Django's CSRF handling.
To remedy this, Django will now apply full CSRF validation to all
requests, regardless of apparent AJAX origin. This is technically
backwards-incompatible, but the security risks have been judged to
outweigh the compatibility concerns in this case.
Additionally, Django will now accept the CSRF token in the custom HTTP
header X-CSRFTOKEN, as well as in the form submission itself, for ease
of use with popular JavaScript toolkits which allow insertion of
custom headers into all AJAX requests.
The following example using the jQuery JavaScript toolkit demonstrates
this; the call to jQuery's ajaxSetup will cause all AJAX requests to
send back the CSRF token in the custom X-CSRFTOKEN header::
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken",
$("#csrfmiddlewaretoken").val());
}
}
});

View File

@ -7,7 +7,7 @@ Welcome to Django 1.2.5!
This is the fifth "bugfix" release in the Django 1.2 series, This is the fifth "bugfix" release in the Django 1.2 series,
improving the stability and performance of the Django 1.2 codebase. improving the stability and performance of the Django 1.2 codebase.
With three exceptions, Django 1.2.5 maintains backwards compatibility With four exceptions, Django 1.2.5 maintains backwards compatibility
with Django 1.2.4, but contain a number of fixes and other with Django 1.2.4, but contain a number of fixes and other
improvements. Django 1.2.5 is a recommended upgrade for any improvements. Django 1.2.5 is a recommended upgrade for any
development or deployment currently using or targeting Django 1.2. development or deployment currently using or targeting Django 1.2.
@ -67,14 +67,28 @@ this; the call to jQuery's ajaxSetup will cause all AJAX requests to
send back the CSRF token in the custom X-CSRFTOKEN header:: send back the CSRF token in the custom X-CSRFTOKEN header::
$.ajaxSetup({ $.ajaxSetup({
beforeSend: function(xhr, settings) { beforeSend: function(xhr, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) { function getCookie(name) {
// Only send the token to relative URLs i.e. locally. var cookieValue = null;
xhr.setRequestHeader("X-CSRFToken", if (document.cookie && document.cookie != '') {
$("#csrfmiddlewaretoken").val()); var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
} }
return cookieValue;
} }
}); if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
FileField no longer deletes files FileField no longer deletes files

View File

@ -261,6 +261,80 @@ requests. These include:
Backwards-incompatible changes in 1.3 Backwards-incompatible changes in 1.3
===================================== =====================================
CSRF exception for AJAX requests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Django includes a CSRF-protection mechanism, which makes use of a
token inserted into outgoing forms. Middleware then checks for the
token's presence on form submission, and validates it.
Prior to Django 1.2.5, our CSRF protection made an exception for AJAX
requests, on the following basis:
* Many AJAX toolkits add an X-Requested-With header when using
XMLHttpRequest.
* Browsers have strict same-origin policies regarding
XMLHttpRequest.
* In the context of a browser, the only way that a custom header
of this nature can be added is with XMLHttpRequest.
Therefore, for ease of use, we did not apply CSRF checks to requests
that appeared to be AJAX on the basis of the X-Requested-With header.
The Ruby on Rails web framework had a similar exemption.
Recently, engineers at Google made members of the Ruby on Rails
development team aware of a combination of browser plugins and
redirects which can allow an attacker to provide custom HTTP headers
on a request to any website. This can allow a forged request to appear
to be an AJAX request, thereby defeating CSRF protection which trusts
the same-origin nature of AJAX requests.
Michael Koziarski of the Rails team brought this to our attention, and
we were able to produce a proof-of-concept demonstrating the same
vulnerability in Django's CSRF handling.
To remedy this, Django will now apply full CSRF validation to all
requests, regardless of apparent AJAX origin. This is technically
backwards-incompatible, but the security risks have been judged to
outweigh the compatibility concerns in this case.
Additionally, Django will now accept the CSRF token in the custom HTTP
header X-CSRFTOKEN, as well as in the form submission itself, for ease
of use with popular JavaScript toolkits which allow insertion of
custom headers into all AJAX requests.
The following example using the jQuery JavaScript toolkit demonstrates
this; the call to jQuery's ajaxSetup will cause all AJAX requests to
send back the CSRF token in the custom X-CSRFTOKEN header::
$.ajaxSetup({
beforeSend: function(xhr, settings) {
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
FileField no longer deletes files FileField no longer deletes files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -36,6 +36,7 @@ Final releases
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
1.1.4
1.1.2 1.1.2
1.1 1.1