diff options
Diffstat (limited to 'parts/django/docs/ref/contrib/csrf.txt')
-rw-r--r-- | parts/django/docs/ref/contrib/csrf.txt | 433 |
1 files changed, 0 insertions, 433 deletions
diff --git a/parts/django/docs/ref/contrib/csrf.txt b/parts/django/docs/ref/contrib/csrf.txt deleted file mode 100644 index c32dd73..0000000 --- a/parts/django/docs/ref/contrib/csrf.txt +++ /dev/null @@ -1,433 +0,0 @@ -===================================== -Cross Site Request Forgery protection -===================================== - -.. module:: django.middleware.csrf - :synopsis: Protects against Cross Site Request Forgeries - -The CSRF middleware and template tag provides easy-to-use protection against -`Cross Site Request Forgeries`_. This type of attack occurs when a malicious -Web site contains a link, a form button or some javascript that is intended to -perform some action on your Web site, using the credentials of a logged-in user -who visits the malicious site in their browser. A related type of attack, -'login CSRF', where an attacking site tricks a user's browser into logging into -a site with someone else's credentials, is also covered. - -The first defense against CSRF attacks is to ensure that GET requests are -side-effect free. POST requests can then be protected by following the steps -below. - -.. versionadded:: 1.2 - The 'contrib' apps, including the admin, use the functionality described - here. Because it is security related, a few things have been added to core - functionality to allow this to happen without any required upgrade steps. - -.. _Cross Site Request Forgeries: http://www.squarefree.com/securitytips/web-developers.html#CSRF - -How to use it -============= - -.. versionchanged:: 1.2 - The template tag functionality (the recommended way to use this) was added - in version 1.2. The previous method (still available) is described under - `Legacy method`_. - -To enable CSRF protection for your views, follow these steps: - - 1. Add the middleware - ``'django.middleware.csrf.CsrfViewMiddleware'`` to your list of - middleware classes, :setting:`MIDDLEWARE_CLASSES`. (It should come - before ``CsrfResponseMiddleware`` if that is being used, and before any - view middleware that assume that CSRF attacks have been dealt with.) - - Alternatively, you can use the decorator - ``django.views.decorators.csrf.csrf_protect`` on particular views you - want to protect (see below). - - 2. In any template that uses a POST form, use the :ttag:`csrf_token` tag inside - the ``<form>`` element if the form is for an internal URL, e.g.:: - - <form action="" method="post">{% csrf_token %} - - This should not be done for POST forms that target external URLs, since - that would cause the CSRF token to be leaked, leading to a vulnerability. - - 3. In the corresponding view functions, ensure that the - ``'django.core.context_processors.csrf'`` context processor is - being used. Usually, this can be done in one of two ways: - - 1. Use RequestContext, which always uses - ``'django.core.context_processors.csrf'`` (no matter what your - TEMPLATE_CONTEXT_PROCESSORS setting). If you are using - generic views or contrib apps, you are covered already, since these - apps use RequestContext throughout. - - 2. Manually import and use the processor to generate the CSRF token and - add it to the template context. e.g.:: - - from django.core.context_processors import csrf - from django.shortcuts import render_to_response - - def my_view(request): - c = {} - c.update(csrf(request)) - # ... view code here - return render_to_response("a_template.html", c) - - You may want to write your own ``render_to_response`` wrapper that - takes care of this step for you. - -The utility script ``extras/csrf_migration_helper.py`` can help to automate the -finding of code and templates that may need to be upgraded. It contains full -help on how to use it. - -The decorator method --------------------- - -Rather than adding ``CsrfViewMiddleware`` as a blanket protection, you can use -the ``csrf_protect`` decorator, which has exactly the same functionality, on -particular views that need the protection. It must be used **both** on views -that insert the CSRF token in the output, and on those that accept the POST form -data. (These are often the same view function, but not always). It is used like -this:: - - from django.views.decorators.csrf import csrf_protect - from django.template import RequestContext - - @csrf_protect - def my_view(request): - c = {} - # ... - return render_to_response("a_template.html", c, - context_instance=RequestContext(request)) - -Use of the decorator is **not recommended** by itself, since if you forget to -use it, you will have a security hole. The 'belt and braces' strategy of using -both is fine, and will incur minimal overhead. - -Legacy method -------------- - -In Django 1.1, the template tag did not exist. Instead, a post-processing -middleware that re-wrote POST forms to include the CSRF token was used. If you -are upgrading a site from version 1.1 or earlier, please read this section and -the `Upgrading notes`_ below. The post-processing middleware is still available -as ``CsrfResponseMiddleware``, and it can be used by following these steps: - - 1. Follow step 1 above to install ``CsrfViewMiddleware``. - - 2. Add ``'django.middleware.csrf.CsrfResponseMiddleware'`` to your - :setting:`MIDDLEWARE_CLASSES` setting. - - ``CsrfResponseMiddleware`` needs to process the response before things - like compression or setting ofETags happen to the response, so it must - come after ``GZipMiddleware``, ``CommonMiddleware`` and - ``ConditionalGetMiddleware`` in the list. It also must come after - ``CsrfViewMiddleware``. - -Use of the ``CsrfResponseMiddleware`` is not recommended because of the -performance hit it imposes, and because of a potential security problem (see -below). It can be used as an interim measure until applications have been -updated to use the :ttag:`csrf_token` tag. It is deprecated and will be -removed in Django 1.4. - -Django 1.1 and earlier provided a single ``CsrfMiddleware`` class. This is also -still available for backwards compatibility. It combines the functions of the -two middleware. - -Note also that previous versions of these classes depended on the sessions -framework, but this dependency has now been removed, with backward compatibility -support so that upgrading will not produce any issues. - -Security of legacy method -~~~~~~~~~~~~~~~~~~~~~~~~~ - -The post-processing ``CsrfResponseMiddleware`` adds the CSRF token to all POST -forms (unless the view has been decorated with ``csrf_response_exempt``). If -the POST form has an external untrusted site as its target, rather than an -internal page, that site will be sent the CSRF token when the form is submitted. -Armed with this leaked information, that site will then be able to successfully -launch a CSRF attack on your site against that user. The -``@csrf_response_exempt`` decorator can be used to fix this, but only if the -page doesn't also contain internal forms that require the token. - -.. _ref-csrf-upgrading-notes: - -Upgrading notes ---------------- - -When upgrading to version 1.2 or later, you may have applications that rely on -the old post-processing functionality for CSRF protection, or you may not have -enabled any CSRF protection. This section outlines the steps necessary for a -smooth upgrade, without having to fix all the applications to use the new -template tag method immediately. - -First of all, the location of the middleware and related functions have -changed. There are backwards compatible stub files so that old imports will -continue to work for now, but they are deprecated and will be removed in Django -1.4. The following changes have been made: - - * Middleware have been moved to ``django.middleware.csrf`` - * Decorators have been moved to ``django.views.decorators.csrf`` - -====================================================== ============================================== - Old New -====================================================== ============================================== -django.contrib.csrf.middleware.CsrfMiddleware django.middleware.csrf.CsrfMiddleware -django.contrib.csrf.middleware.CsrfViewMiddleware django.middleware.csrf.CsrfViewMiddleware -django.contrib.csrf.middleware.CsrfResponseMiddleware django.middleware.csrf.CsrfResponseMiddleware -django.contrib.csrf.middleware.csrf_exempt django.views.decorators.csrf.csrf_exempt -django.contrib.csrf.middleware.csrf_view_exempt django.views.decorators.csrf.csrf_view_exempt -django.contrib.csrf.middleware.csrf_response_exempt django.views.decorators.csrf.csrf_response_exempt -====================================================== ============================================== - -You should update any imports, and also the paths in your -:setting:`MIDDLEWARE_CLASSES`. - -If you have ``CsrfMiddleware`` in your :setting:`MIDDLEWARE_CLASSES`, you will now -have a working installation with CSRF protection. It is recommended at this -point that you replace ``CsrfMiddleware`` with its two components, -``CsrfViewMiddleware`` and ``CsrfResponseMiddleware`` (in that order). - -If you do not have any of the middleware in your :setting:`MIDDLEWARE_CLASSES`, -you will have a working installation but without any CSRF protection for your -views (just as you had before). It is strongly recommended to install -``CsrfViewMiddleware`` and ``CsrfResponseMiddleware``, as described above. - -Note that contrib apps, such as the admin, have been updated to use the -``csrf_protect`` decorator, so that they are secured even if you do not add the -``CsrfViewMiddleware`` to your settings. However, if you have supplied -customised templates to any of the view functions of contrib apps (whether -explicitly via a keyword argument, or by overriding built-in templates), **you -MUST update them** to include the :ttag:`csrf_token` template tag as described -above, or they will stop working. (If you cannot update these templates for -some reason, you will be forced to use ``CsrfResponseMiddleware`` for these -views to continue working). - -Note also, if you are using the comments app, and you are not going to add -``CsrfViewMiddleware`` to your settings (not recommended), you will need to add -the ``csrf_protect`` decorator to any views that include the comment forms and -target the comment views (usually using the :ttag:`comment_form_target` template -tag). - -Assuming you have followed the above, all views in your Django site will now be -protected by the ``CsrfViewMiddleware``. Contrib apps meet the requirements -imposed by the ``CsrfViewMiddleware`` using the template tag, and other -applications in your project will meet its requirements by virtue of the -``CsrfResponseMiddleware``. - -The next step is to update all your applications to use the template tag, as -described in `How to use it`_, steps 2-3. This can be done as soon as is -practical. Any applications that are updated will now require Django 1.1.2 or -later, since they will use the CSRF template tag which was not available in -earlier versions. (The template tag in 1.1.2 is actually a no-op that exists -solely to ease the transition to 1.2 — it allows apps to be created that have -CSRF protection under 1.2 without requiring users of the apps to upgrade to the -Django 1.2.X series). - -The utility script ``extras/csrf_migration_helper.py`` can help to automate the -finding of code and templates that may need to be upgraded. It contains full -help on how to use it. - -Finally, once all applications are upgraded, ``CsrfResponseMiddleware`` can be -removed from your settings. - -While ``CsrfResponseMiddleware`` is still in use, the ``csrf_response_exempt`` -decorator, described in `Exceptions`_, may be useful. The post-processing -middleware imposes a performance hit and a potential vulnerability, and any -views that have been upgraded to use the new template tag method no longer need -it. - -Exceptions ----------- - -.. versionadded:: 1.1 -.. versionchanged:: 1.2 - Import paths for the decorators below were changed. - -To manually exclude a view function from being handled by either of the two CSRF -middleware, you can use the ``csrf_exempt`` decorator, found in the -``django.views.decorators.csrf`` module. For example:: - - from django.views.decorators.csrf import csrf_exempt - - @csrf_exempt - def my_view(request): - return HttpResponse('Hello world') - -Like the middleware, the ``csrf_exempt`` decorator is composed of two parts: a -``csrf_view_exempt`` decorator and a ``csrf_response_exempt`` decorator, found -in the same module. These disable the view protection mechanism -(``CsrfViewMiddleware``) and the response post-processing -(``CsrfResponseMiddleware``) respectively. They can be used individually if -required. - -You don't have to worry about doing this for most AJAX views. Any request sent -with "X-Requested-With: XMLHttpRequest" is automatically exempt. (See the `How -it works`_ section.) - -Subdomains ----------- - -By default, CSRF cookies are specific to the subdomain they are set for. This -means that a form served from one subdomain (e.g. server1.example.com) will not -be able to have a target on another subdomain (e.g. server2.example.com). This -restriction can be removed by setting :setting:`CSRF_COOKIE_DOMAIN` to be -something like ``".example.com"``. - -Please note that, with or without use of this setting, this CSRF protection -mechanism is not safe against cross-subdomain attacks -- see `Limitations`_. - -Rejected requests -================= - -By default, a '403 Forbidden' response is sent to the user if an incoming -request fails the checks performed by ``CsrfViewMiddleware``. This should -usually only be seen when there is a genuine Cross Site Request Forgery, or -when, due to a programming error, the CSRF token has not been included with a -POST form. - -No logging is done, and the error message is not very friendly, so you may want -to provide your own page for handling this condition. To do this, simply set -the :setting:`CSRF_FAILURE_VIEW` setting to a dotted path to your own view -function, which should have the following signature:: - - def csrf_failure(request, reason="") - -where ``reason`` is a short message (intended for developers or logging, not for -end users) indicating the reason the request was rejected. - -How it works -============ - -The CSRF protection is based on the following things: - -1. A CSRF cookie that is set to a random value (a session independent nonce, as - it is called), which other sites will not have access to. - - This cookie is set by ``CsrfViewMiddleware``. It is meant to be permanent, - but since there is no way to set a cookie that never expires, it is sent with - every response that has called ``django.middleware.csrf.get_token()`` - (the function used internally to retrieve the CSRF token). - -2. A hidden form field with the name 'csrfmiddlewaretoken' present in all - outgoing POST forms. The value of this field is the value of the CSRF - cookie. - - This part is done by the template tag (and with the legacy method, it is done - by ``CsrfResponseMiddleware``). - -3. For all incoming POST requests, a CSRF cookie must be present, and the - 'csrfmiddlewaretoken' field must be present and correct. If it isn't, the - user will get a 403 error. - - This check is done by ``CsrfViewMiddleware``. - -4. In addition, for HTTPS requests, strict referer checking is done by - ``CsrfViewMiddleware``. This is necessary to address a Man-In-The-Middle - attack that is possible under HTTPS when using a session independent nonce, - due to the fact that HTTP 'Set-Cookie' headers are (unfortunately) accepted - by clients that are talking to a site under HTTPS. (Referer checking is not - done for HTTP requests because the presence of the Referer header is not - reliable enough under HTTP.) - -This ensures that only forms that have originated from your Web site can be used -to POST data back. - -It deliberately only targets HTTP POST requests (and the corresponding POST -forms). GET requests ought never to have any potentially dangerous side effects -(see `9.1.1 Safe Methods, HTTP 1.1, RFC 2616`_), and so a CSRF attack with a GET -request ought to be harmless. - -``CsrfResponseMiddleware`` checks the Content-Type before modifying the -response, and only pages that are served as 'text/html' or -'application/xml+xhtml' are modified. - -AJAX ----- - -The middleware tries to be smart about requests that come in via AJAX. Most -modern JavaScript toolkits send an "X-Requested-With: XMLHttpRequest" HTTP -header; these requests are detected and automatically *not* handled by this -middleware. We can do this safely because, in the context of a browser, the -header can only be added by using ``XMLHttpRequest``, and browsers already -implement a same-domain policy for ``XMLHttpRequest``. - -For the more recent browsers that relax this same-domain policy, custom headers -like "X-Requested-With" are only allowed after the browser has done a -'preflight' check to the server to see if the cross-domain request is allowed, -using a strictly 'opt in' mechanism, so the exception for AJAX is still safe—if -the developer has specifically opted in to allowing cross-site AJAX POST -requests on a specific URL, they obviously don't want the middleware to disallow -exactly that. - -.. _9.1.1 Safe Methods, HTTP 1.1, RFC 2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html - -Caching -======= - -If the :ttag:`csrf_token` template tag is used by a template (or the ``get_token`` -function is called some other way), ``CsrfViewMiddleware`` will add a cookie and -a ``Vary: Cookie`` header to the response. Similarly, -``CsrfResponseMiddleware`` will send the ``Vary: Cookie`` header if it inserted -a token. This means that these middleware will play well with the cache -middleware if it is used as instructed (``UpdateCacheMiddleware`` goes before -all other middleware). - -However, if you use cache decorators on individual views, the CSRF middleware -will not yet have been able to set the Vary header. In this case, on any views -that will require a CSRF token to be inserted you should use the -:func:`django.views.decorators.vary.vary_on_cookie` decorator first:: - - from django.views.decorators.cache import cache_page - from django.views.decorators.vary import vary_on_cookie - - @cache_page(60 * 15) - @vary_on_cookie - def my_view(request): - # ... - - -Testing -======= - -The ``CsrfViewMiddleware`` will usually be a big hindrance to testing view -functions, due to the need for the CSRF token which must be sent with every POST -request. For this reason, Django's HTTP client for tests has been modified to -set a flag on requests which relaxes the middleware and the ``csrf_protect`` -decorator so that they no longer rejects requests. In every other respect -(e.g. sending cookies etc.), they behave the same. - -If, for some reason, you *want* the test client to perform CSRF -checks, you can create an instance of the test client that enforces -CSRF checks:: - - >>> from django.test import Client - >>> csrf_client = Client(enforce_csrf_checks=True) - -Limitations -=========== - -Subdomains within a site will be able to set cookies on the client for the whole -domain. By setting the cookie and using a corresponding token, subdomains will -be able to circumvent the CSRF protection. The only way to avoid this is to -ensure that subdomains are controlled by trusted users (or, are at least unable -to set cookies). Note that even without CSRF, there are other vulnerabilities, -such as session fixation, that make giving subdomains to untrusted parties a bad -idea, and these vulnerabilities cannot easily be fixed with current browsers. - -If you are using ``CsrfResponseMiddleware`` and your app creates HTML pages and -forms in some unusual way, (e.g. it sends fragments of HTML in JavaScript -document.write statements) you might bypass the filter that adds the hidden -field to the form, in which case form submission will always fail. You should -use the template tag or :meth:`django.middleware.csrf.get_token` to get -the CSRF token and ensure it is included when your form is submitted. - -Contrib and reusable apps -========================= - -Because it is possible for the developer to turn off the ``CsrfViewMiddleware``, -all relevant views in contrib apps use the ``csrf_protect`` decorator to ensure -the security of these applications against CSRF. It is recommended that the -developers of other reusable apps that want the same guarantees also use the -``csrf_protect`` decorator on their views. |