/docs/ref/contrib/csrf.txt
Plain Text | 472 lines | 370 code | 102 blank | 0 comment | 0 complexity | 1796f55fb4b6e95ed06c06f8b0a51116 MD5 | raw file
1===================================== 2Cross Site Request Forgery protection 3===================================== 4 5.. module:: django.middleware.csrf 6 :synopsis: Protects against Cross Site Request Forgeries 7 8The CSRF middleware and template tag provides easy-to-use protection against 9`Cross Site Request Forgeries`_. This type of attack occurs when a malicious 10Web site contains a link, a form button or some javascript that is intended to 11perform some action on your Web site, using the credentials of a logged-in user 12who visits the malicious site in their browser. A related type of attack, 13'login CSRF', where an attacking site tricks a user's browser into logging into 14a site with someone else's credentials, is also covered. 15 16The first defense against CSRF attacks is to ensure that GET requests are 17side-effect free. POST requests can then be protected by following the steps 18below. 19 20.. versionadded:: 1.2 21 The 'contrib' apps, including the admin, use the functionality described 22 here. Because it is security related, a few things have been added to core 23 functionality to allow this to happen without any required upgrade steps. 24 25.. _Cross Site Request Forgeries: http://www.squarefree.com/securitytips/web-developers.html#CSRF 26 27How to use it 28============= 29 30.. versionchanged:: 1.2 31 The template tag functionality (the recommended way to use this) was added 32 in version 1.2. The previous method (still available) is described under 33 `Legacy method`_. 34 35To enable CSRF protection for your views, follow these steps: 36 37 1. Add the middleware 38 ``'django.middleware.csrf.CsrfViewMiddleware'`` to your list of 39 middleware classes, :setting:`MIDDLEWARE_CLASSES`. (It should come 40 before ``CsrfResponseMiddleware`` if that is being used, and before any 41 view middleware that assume that CSRF attacks have been dealt with.) 42 43 Alternatively, you can use the decorator 44 ``django.views.decorators.csrf.csrf_protect`` on particular views you 45 want to protect (see below). 46 47 2. In any template that uses a POST form, use the :ttag:`csrf_token` tag inside 48 the ``<form>`` element if the form is for an internal URL, e.g.:: 49 50 <form action="" method="post">{% csrf_token %} 51 52 This should not be done for POST forms that target external URLs, since 53 that would cause the CSRF token to be leaked, leading to a vulnerability. 54 55 3. In the corresponding view functions, ensure that the 56 ``'django.core.context_processors.csrf'`` context processor is 57 being used. Usually, this can be done in one of two ways: 58 59 1. Use RequestContext, which always uses 60 ``'django.core.context_processors.csrf'`` (no matter what your 61 TEMPLATE_CONTEXT_PROCESSORS setting). If you are using 62 generic views or contrib apps, you are covered already, since these 63 apps use RequestContext throughout. 64 65 2. Manually import and use the processor to generate the CSRF token and 66 add it to the template context. e.g.:: 67 68 from django.core.context_processors import csrf 69 from django.shortcuts import render_to_response 70 71 def my_view(request): 72 c = {} 73 c.update(csrf(request)) 74 # ... view code here 75 return render_to_response("a_template.html", c) 76 77 You may want to write your own ``render_to_response`` wrapper that 78 takes care of this step for you. 79 80The utility script ``extras/csrf_migration_helper.py`` can help to automate the 81finding of code and templates that may need to be upgraded. It contains full 82help on how to use it. 83 84.. _csrf-ajax: 85 86AJAX 87---- 88 89While the above method can be used for AJAX POST requests, it has some 90inconveniences: you have to remember to pass the CSRF token in as POST data with 91every POST request. For this reason, there is an alternative method: on each 92XMLHttpRequest, set a custom `X-CSRFToken` header to the value of the CSRF 93token. This is often easier, because many javascript frameworks provide hooks 94that allow headers to be set on every request. In jQuery, you can use the 95``ajaxSend`` event as follows: 96 97.. code-block:: javascript 98 99 $(document).ajaxSend(function(event, xhr, settings) { 100 function getCookie(name) { 101 var cookieValue = null; 102 if (document.cookie && document.cookie != '') { 103 var cookies = document.cookie.split(';'); 104 for (var i = 0; i < cookies.length; i++) { 105 var cookie = jQuery.trim(cookies[i]); 106 // Does this cookie string begin with the name we want? 107 if (cookie.substring(0, name.length + 1) == (name + '=')) { 108 cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 109 break; 110 } 111 } 112 } 113 return cookieValue; 114 } 115 function sameOrigin(url) { 116 // url could be relative or scheme relative or absolute 117 var host = document.location.host; // host + port 118 var protocol = document.location.protocol; 119 var sr_origin = '//' + host; 120 var origin = protocol + sr_origin; 121 // Allow absolute or scheme relative URLs to same origin 122 return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || 123 (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || 124 // or any other URL that isn't scheme relative or absolute i.e relative. 125 !(/^(\/\/|http:|https:).*/.test(url)); 126 } 127 function safeMethod(method) { 128 return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 129 } 130 131 if (!safeMethod(settings.type) && sameOrigin(settings.url)) { 132 xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); 133 } 134 }); 135 136.. note:: 137 138 Due to a bug introduced in jQuery 1.5, the example above will not work 139 correctly on that version. Make sure you are running at least jQuery 1.5.1. 140 141Adding this to a javascript file that is included on your site will ensure that 142AJAX POST requests that are made via jQuery will not be caught by the CSRF 143protection. 144 145The decorator method 146-------------------- 147 148Rather than adding ``CsrfViewMiddleware`` as a blanket protection, you can use 149the ``csrf_protect`` decorator, which has exactly the same functionality, on 150particular views that need the protection. It must be used **both** on views 151that insert the CSRF token in the output, and on those that accept the POST form 152data. (These are often the same view function, but not always). It is used like 153this:: 154 155 from django.views.decorators.csrf import csrf_protect 156 from django.template import RequestContext 157 158 @csrf_protect 159 def my_view(request): 160 c = {} 161 # ... 162 return render_to_response("a_template.html", c, 163 context_instance=RequestContext(request)) 164 165Use of the decorator is **not recommended** by itself, since if you forget to 166use it, you will have a security hole. The 'belt and braces' strategy of using 167both is fine, and will incur minimal overhead. 168 169Legacy method 170------------- 171 172In Django 1.1, the template tag did not exist. Instead, a post-processing 173middleware that re-wrote POST forms to include the CSRF token was used. If you 174are upgrading a site from version 1.1 or earlier, please read this section and 175the `Upgrading notes`_ below. The post-processing middleware is still available 176as ``CsrfResponseMiddleware``, and it can be used by following these steps: 177 178 1. Follow step 1 above to install ``CsrfViewMiddleware``. 179 180 2. Add ``'django.middleware.csrf.CsrfResponseMiddleware'`` to your 181 :setting:`MIDDLEWARE_CLASSES` setting. 182 183 ``CsrfResponseMiddleware`` needs to process the response before things 184 like compression or setting ofETags happen to the response, so it must 185 come after ``GZipMiddleware``, ``CommonMiddleware`` and 186 ``ConditionalGetMiddleware`` in the list. It also must come after 187 ``CsrfViewMiddleware``. 188 189Use of the ``CsrfResponseMiddleware`` is not recommended because of the 190performance hit it imposes, and because of a potential security problem (see 191below). It can be used as an interim measure until applications have been 192updated to use the :ttag:`csrf_token` tag. It is deprecated and will be 193removed in Django 1.4. 194 195Django 1.1 and earlier provided a single ``CsrfMiddleware`` class. This is also 196still available for backwards compatibility. It combines the functions of the 197two middleware. 198 199Note also that previous versions of these classes depended on the sessions 200framework, but this dependency has now been removed, with backward compatibility 201support so that upgrading will not produce any issues. 202 203Security of legacy method 204~~~~~~~~~~~~~~~~~~~~~~~~~ 205 206The post-processing ``CsrfResponseMiddleware`` adds the CSRF token to all POST 207forms (unless the view has been decorated with ``csrf_response_exempt``). If 208the POST form has an external untrusted site as its target, rather than an 209internal page, that site will be sent the CSRF token when the form is submitted. 210Armed with this leaked information, that site will then be able to successfully 211launch a CSRF attack on your site against that user. The 212``@csrf_response_exempt`` decorator can be used to fix this, but only if the 213page doesn't also contain internal forms that require the token. 214 215.. _ref-csrf-upgrading-notes: 216 217Upgrading notes 218--------------- 219 220When upgrading to version 1.2 or later, you may have applications that rely on 221the old post-processing functionality for CSRF protection, or you may not have 222enabled any CSRF protection. This section outlines the steps necessary for a 223smooth upgrade, without having to fix all the applications to use the new 224template tag method immediately. 225 226First of all, the location of the middleware and related functions have 227changed. There are backwards compatible stub files so that old imports will 228continue to work for now, but they are deprecated and will be removed in Django 2291.4. The following changes have been made: 230 231 * Middleware have been moved to ``django.middleware.csrf`` 232 * Decorators have been moved to ``django.views.decorators.csrf`` 233 234====================================================== ============================================== 235 Old New 236====================================================== ============================================== 237django.contrib.csrf.middleware.CsrfMiddleware django.middleware.csrf.CsrfMiddleware 238django.contrib.csrf.middleware.CsrfViewMiddleware django.middleware.csrf.CsrfViewMiddleware 239django.contrib.csrf.middleware.CsrfResponseMiddleware django.middleware.csrf.CsrfResponseMiddleware 240django.contrib.csrf.middleware.csrf_exempt django.views.decorators.csrf.csrf_exempt 241django.contrib.csrf.middleware.csrf_view_exempt django.views.decorators.csrf.csrf_view_exempt 242django.contrib.csrf.middleware.csrf_response_exempt django.views.decorators.csrf.csrf_response_exempt 243====================================================== ============================================== 244 245You should update any imports, and also the paths in your 246:setting:`MIDDLEWARE_CLASSES`. 247 248If you have ``CsrfMiddleware`` in your :setting:`MIDDLEWARE_CLASSES`, you will now 249have a working installation with CSRF protection. It is recommended at this 250point that you replace ``CsrfMiddleware`` with its two components, 251``CsrfViewMiddleware`` and ``CsrfResponseMiddleware`` (in that order). 252 253If you do not have any of the middleware in your :setting:`MIDDLEWARE_CLASSES`, 254you will have a working installation but without any CSRF protection for your 255views (just as you had before). It is strongly recommended to install 256``CsrfViewMiddleware`` and ``CsrfResponseMiddleware``, as described above. 257 258Note that contrib apps, such as the admin, have been updated to use the 259``csrf_protect`` decorator, so that they are secured even if you do not add the 260``CsrfViewMiddleware`` to your settings. However, if you have supplied 261customised templates to any of the view functions of contrib apps (whether 262explicitly via a keyword argument, or by overriding built-in templates), **you 263MUST update them** to include the :ttag:`csrf_token` template tag as described 264above, or they will stop working. (If you cannot update these templates for 265some reason, you will be forced to use ``CsrfResponseMiddleware`` for these 266views to continue working). 267 268Note also, if you are using the comments app, and you are not going to add 269``CsrfViewMiddleware`` to your settings (not recommended), you will need to add 270the ``csrf_protect`` decorator to any views that include the comment forms and 271target the comment views (usually using the :ttag:`comment_form_target` template 272tag). 273 274Assuming you have followed the above, all views in your Django site will now be 275protected by the ``CsrfViewMiddleware``. Contrib apps meet the requirements 276imposed by the ``CsrfViewMiddleware`` using the template tag, and other 277applications in your project will meet its requirements by virtue of the 278``CsrfResponseMiddleware``. 279 280The next step is to update all your applications to use the template tag, as 281described in `How to use it`_, steps 2-3. This can be done as soon as is 282practical. Any applications that are updated will now require Django 1.1.2 or 283later, since they will use the CSRF template tag which was not available in 284earlier versions. (The template tag in 1.1.2 is actually a no-op that exists 285solely to ease the transition to 1.2 รข€” it allows apps to be created that have 286CSRF protection under 1.2 without requiring users of the apps to upgrade to the 287Django 1.2.X series). 288 289The utility script ``extras/csrf_migration_helper.py`` can help to automate the 290finding of code and templates that may need to be upgraded. It contains full 291help on how to use it. 292 293Finally, once all applications are upgraded, ``CsrfResponseMiddleware`` can be 294removed from your settings. 295 296While ``CsrfResponseMiddleware`` is still in use, the ``csrf_response_exempt`` 297decorator, described in `Exceptions`_, may be useful. The post-processing 298middleware imposes a performance hit and a potential vulnerability, and any 299views that have been upgraded to use the new template tag method no longer need 300it. 301 302Exceptions 303---------- 304 305.. versionchanged:: 1.2 306 Import paths for the decorators below were changed. 307 308To manually exclude a view function from being handled by either of the two CSRF 309middleware, you can use the ``csrf_exempt`` decorator, found in the 310``django.views.decorators.csrf`` module. For example:: 311 312 from django.views.decorators.csrf import csrf_exempt 313 314 @csrf_exempt 315 def my_view(request): 316 return HttpResponse('Hello world') 317 318Like the middleware, the ``csrf_exempt`` decorator is composed of two parts: a 319``csrf_view_exempt`` decorator and a ``csrf_response_exempt`` decorator, found 320in the same module. These disable the view protection mechanism 321(``CsrfViewMiddleware``) and the response post-processing 322(``CsrfResponseMiddleware``) respectively. They can be used individually if 323required. 324 325Subdomains 326---------- 327 328By default, CSRF cookies are specific to the subdomain they are set for. This 329means that a form served from one subdomain (e.g. server1.example.com) will not 330be able to have a target on another subdomain (e.g. server2.example.com). This 331restriction can be removed by setting :setting:`CSRF_COOKIE_DOMAIN` to be 332something like ``".example.com"``. 333 334Please note that, with or without use of this setting, this CSRF protection 335mechanism is not safe against cross-subdomain attacks -- see `Limitations`_. 336 337Rejected requests 338================= 339 340By default, a '403 Forbidden' response is sent to the user if an incoming 341request fails the checks performed by ``CsrfViewMiddleware``. This should 342usually only be seen when there is a genuine Cross Site Request Forgery, or 343when, due to a programming error, the CSRF token has not been included with a 344POST form. 345 346No logging is done, and the error message is not very friendly, so you may want 347to provide your own page for handling this condition. To do this, simply set 348the :setting:`CSRF_FAILURE_VIEW` setting to a dotted path to your own view 349function, which should have the following signature:: 350 351 def csrf_failure(request, reason="") 352 353where ``reason`` is a short message (intended for developers or logging, not for 354end users) indicating the reason the request was rejected. 355 356How it works 357============ 358 359The CSRF protection is based on the following things: 360 3611. A CSRF cookie that is set to a random value (a session independent nonce, as 362 it is called), which other sites will not have access to. 363 364 This cookie is set by ``CsrfViewMiddleware``. It is meant to be permanent, 365 but since there is no way to set a cookie that never expires, it is sent with 366 every response that has called ``django.middleware.csrf.get_token()`` 367 (the function used internally to retrieve the CSRF token). 368 3692. A hidden form field with the name 'csrfmiddlewaretoken' present in all 370 outgoing POST forms. The value of this field is the value of the CSRF 371 cookie. 372 373 This part is done by the template tag (and with the legacy method, it is done 374 by ``CsrfResponseMiddleware``). 375 3763. For all incoming POST requests, a CSRF cookie must be present, and the 377 'csrfmiddlewaretoken' field must be present and correct. If it isn't, the 378 user will get a 403 error. 379 380 This check is done by ``CsrfViewMiddleware``. 381 3824. In addition, for HTTPS requests, strict referer checking is done by 383 ``CsrfViewMiddleware``. This is necessary to address a Man-In-The-Middle 384 attack that is possible under HTTPS when using a session independent nonce, 385 due to the fact that HTTP 'Set-Cookie' headers are (unfortunately) accepted 386 by clients that are talking to a site under HTTPS. (Referer checking is not 387 done for HTTP requests because the presence of the Referer header is not 388 reliable enough under HTTP.) 389 390This ensures that only forms that have originated from your Web site can be used 391to POST data back. 392 393It deliberately only targets HTTP POST requests (and the corresponding POST 394forms). GET requests ought never to have any potentially dangerous side effects 395(see `9.1.1 Safe Methods, HTTP 1.1, RFC 2616`_), and so a CSRF attack with a GET 396request ought to be harmless. 397 398``CsrfResponseMiddleware`` checks the Content-Type before modifying the 399response, and only pages that are served as 'text/html' or 400'application/xml+xhtml' are modified. 401 402.. _9.1.1 Safe Methods, HTTP 1.1, RFC 2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html 403 404Caching 405======= 406 407If the :ttag:`csrf_token` template tag is used by a template (or the ``get_token`` 408function is called some other way), ``CsrfViewMiddleware`` will add a cookie and 409a ``Vary: Cookie`` header to the response. Similarly, 410``CsrfResponseMiddleware`` will send the ``Vary: Cookie`` header if it inserted 411a token. This means that these middleware will play well with the cache 412middleware if it is used as instructed (``UpdateCacheMiddleware`` goes before 413all other middleware). 414 415However, if you use cache decorators on individual views, the CSRF middleware 416will not yet have been able to set the Vary header or the CSRF cookie, and the 417response will be cached without either one. In this case, on any views that 418will require a CSRF token to be inserted you should use the 419:func:`django.views.decorators.csrf.csrf_protect` decorator first:: 420 421 from django.views.decorators.cache import cache_page 422 from django.views.decorators.csrf import csrf_protect 423 424 @cache_page(60 * 15) 425 @csrf_protect 426 def my_view(request): 427 # ... 428 429 430Testing 431======= 432 433The ``CsrfViewMiddleware`` will usually be a big hindrance to testing view 434functions, due to the need for the CSRF token which must be sent with every POST 435request. For this reason, Django's HTTP client for tests has been modified to 436set a flag on requests which relaxes the middleware and the ``csrf_protect`` 437decorator so that they no longer rejects requests. In every other respect 438(e.g. sending cookies etc.), they behave the same. 439 440If, for some reason, you *want* the test client to perform CSRF 441checks, you can create an instance of the test client that enforces 442CSRF checks:: 443 444 >>> from django.test import Client 445 >>> csrf_client = Client(enforce_csrf_checks=True) 446 447Limitations 448=========== 449 450Subdomains within a site will be able to set cookies on the client for the whole 451domain. By setting the cookie and using a corresponding token, subdomains will 452be able to circumvent the CSRF protection. The only way to avoid this is to 453ensure that subdomains are controlled by trusted users (or, are at least unable 454to set cookies). Note that even without CSRF, there are other vulnerabilities, 455such as session fixation, that make giving subdomains to untrusted parties a bad 456idea, and these vulnerabilities cannot easily be fixed with current browsers. 457 458If you are using ``CsrfResponseMiddleware`` and your app creates HTML pages and 459forms in some unusual way, (e.g. it sends fragments of HTML in JavaScript 460document.write statements) you might bypass the filter that adds the hidden 461field to the form, in which case form submission will always fail. You should 462use the template tag or :meth:`django.middleware.csrf.get_token` to get 463the CSRF token and ensure it is included when your form is submitted. 464 465Contrib and reusable apps 466========================= 467 468Because it is possible for the developer to turn off the ``CsrfViewMiddleware``, 469all relevant views in contrib apps use the ``csrf_protect`` decorator to ensure 470the security of these applications against CSRF. It is recommended that the 471developers of other reusable apps that want the same guarantees also use the 472``csrf_protect`` decorator on their views.