PageRenderTime 348ms CodeModel.GetById 119ms app.highlight 3ms RepoModel.GetById 104ms app.codeStats 1ms

/docs/ref/contrib/csrf.txt

https://code.google.com/p/mango-py/
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 รข&#x20AC;&#x201D; 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.