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:
parent
1ca9ceda59
commit
f913fab6be
|
@ -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());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -7,7 +7,7 @@ Welcome to Django 1.2.5!
|
|||
This is the fifth "bugfix" release in the Django 1.2 series,
|
||||
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
|
||||
improvements. Django 1.2.5 is a recommended upgrade for any
|
||||
development or deployment currently using or targeting Django 1.2.
|
||||
|
@ -68,10 +68,24 @@ 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",
|
||||
$("#csrfmiddlewaretoken").val());
|
||||
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -261,6 +261,80 @@ requests. These include:
|
|||
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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ Final releases
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
1.1.4
|
||||
1.1.2
|
||||
1.1
|
||||
|
||||
|
|
Loading…
Reference in New Issue