{"title":"Django 1.1.4 release notes","version":"dev","locale":"en","docname":"releases/1.1.4","url":"/en/dev/releases/1.1.4/","canonical":"https://djangodocs.dev/en/dev/releases/1.1.4/","summary":"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.","html":"<h1>Django 1.1.4 release notes<a class=\"heading-anchor\" href=\"#django-1-1-4-release-notes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Welcome to Django 1.1.4!</p>\n<p>This is the fourth “bugfix” release in the Django 1.1 series,\nimproving the stability and performance of the Django 1.1 codebase.</p>\n<p>With one exception, Django 1.1.4 maintains backwards compatibility\nwith Django 1.1.3. It also contains a number of fixes and other\nimprovements. Django 1.1.4 is a recommended upgrade for any\ndevelopment or deployment currently using or targeting Django 1.1.</p>\n<p>For full details on the new features, backwards incompatibilities, and\ndeprecated features in the 1.1 branch, see the <a class=\"reference internal\" href=\"/en/dev/releases/1.1/\"><span class=\"doc\">Django 1.1 release notes</span></a>.</p>\n<section id=\"backwards-incompatible-changes\">\n<h2>Backwards incompatible changes<a class=\"heading-anchor\" href=\"#backwards-incompatible-changes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"csrf-exception-for-ajax-requests\">\n<h3>CSRF exception for AJAX requests<a class=\"heading-anchor\" href=\"#csrf-exception-for-ajax-requests\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django includes a CSRF-protection mechanism, which makes use of a\ntoken inserted into outgoing forms. Middleware then checks for the\ntoken’s presence on form submission, and validates it.</p>\n<p>Prior to Django 1.2.5, our CSRF protection made an exception for AJAX\nrequests, on the following basis:</p>\n<ul class=\"simple\">\n<li><p>Many AJAX toolkits add an X-Requested-With header when using\nXMLHttpRequest.</p></li>\n<li><p>Browsers have strict same-origin policies regarding\nXMLHttpRequest.</p></li>\n<li><p>In the context of a browser, the only way that a custom header\nof this nature can be added is with XMLHttpRequest.</p></li>\n</ul>\n<p>Therefore, for ease of use, we did not apply CSRF checks to requests\nthat appeared to be AJAX on the basis of the X-Requested-With header.\nThe Ruby on Rails web framework had a similar exemption.</p>\n<p>Recently, engineers at Google made members of the Ruby on Rails\ndevelopment team aware of a combination of browser plugins and\nredirects which can allow an attacker to provide custom HTTP headers\non a request to any website. This can allow a forged request to appear\nto be an AJAX request, thereby defeating CSRF protection which trusts\nthe same-origin nature of AJAX requests.</p>\n<p>Michael Koziarski of the Rails team brought this to our attention, and\nwe were able to produce a proof-of-concept demonstrating the same\nvulnerability in Django’s CSRF handling.</p>\n<p>To remedy this, Django will now apply full CSRF validation to all\nrequests, regardless of apparent AJAX origin. This is technically\nbackwards-incompatible, but the security risks have been judged to\noutweigh the compatibility concerns in this case.</p>\n<p>Additionally, Django will now accept the CSRF token in the custom HTTP\nheader X-CSRFTOKEN, as well as in the form submission itself, for ease\nof use with popular JavaScript toolkits which allow insertion of\ncustom headers into all AJAX requests.</p>\n<p>Please see the <a class=\"reference internal\" href=\"/en/dev/howto/csrf/#csrf-ajax\"><span class=\"std std-ref\">CSRF docs for example jQuery code</span></a>\nthat demonstrates this technique, ensuring that you are looking at the\ndocumentation for your version of Django, as the exact code necessary\nis different for some older versions of Django.</p>\n</section>\n</section>","rootId":"django-1-1-4-release-notes","toc":[{"title":"Backwards incompatible changes","anchor":"backwards-incompatible-changes","children":[{"title":"CSRF exception for AJAX requests","anchor":"csrf-exception-for-ajax-requests","children":[]}]}],"breadcrumbs":[{"docname":"releases/index","title":"Release notes","url":"/en/dev/releases/"}],"prev":{"docname":"releases/1.2","title":"Django 1.2 release notes","url":"/en/dev/releases/1.2/"},"next":{"docname":"releases/1.1.3","title":"Django 1.1.3 release notes","url":"/en/dev/releases/1.1.3/"},"formats":{"html":"/en/dev/releases/1.1.4/","markdown":"/en/dev/releases/1.1.4.md","json":"/en/dev/releases/1.1.4.json"},"source":"https://github.com/django/django/blob/main/docs/releases/1.1.4.txt","official":"https://docs.djangoproject.com/en/dev/releases/1.1.4/","inVersions":["dev","6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9","1.8"],"inLocales":["en"]}