django/docs/ref/contrib/csrf.txt

126 lines
5.1 KiB
Plaintext
Raw Normal View History

.. _ref-contrib-csrf:
=====================================
Cross Site Request Forgery protection
=====================================
.. module:: django.contrib.csrf
:synopsis: Protects against Cross Site Request Forgeries
The CsrfMiddleware classes provides easy-to-use protection against
`Cross Site Request Forgeries`_. This type of attack occurs when a
malicious Web site creates a link or form button that is intended to
perform some action on your Web site, using the credentials of a
logged-in user who is tricked into clicking on the link in their
browser.
The first defense against CSRF attacks is to ensure that GET requests
are side-effect free. POST requests can then be protected by adding
these middleware into your list of installed middleware.
.. _Cross Site Request Forgeries: http://www.squarefree.com/securitytips/web-developers.html#CSRF
How to use it
=============
Add the middleware
``'django.contrib.csrf.middleware.CsrfViewMiddleware'`` and
``'django.contrib.csrf.middleware.CsrfResponseMiddleware'`` to your
list of middleware classes,
:setting:`MIDDLEWARE_CLASSES`. ``CsrfResponseMiddleware`` needs to
process the response after the ``SessionMiddleware``, so must come
before it in the list. It also must process the response before
things like compression happen to the response, so it must come after
``GZipMiddleware`` in the list.
The ``CsrfMiddleware`` class, which combines the two classes, is also
available, for backwards compatibility with Django 1.0.
.. versionchanged:: 1.1
previous versions of Django did not provide these two components
of ``CsrfMiddleware`` as described above.
Exceptions
----------
.. versionadded:: 1.1
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.contrib.csrf.middleware`` module. For example::
from django.contrib.csrf.middleware import csrf_exempt
def my_view(request):
return HttpResponse('Hello world')
my_view = csrf_exempt(my_view)
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 next section.)
How it works
============
The CSRF middleware do two things:
1. It modifies outgoing requests by adding a hidden form field to all
'POST' forms, with the name 'csrfmiddlewaretoken' and a value which is
a hash of the session ID plus a secret. If there is no session ID set,
this modification of the response isn't done, so there is very little
performance penalty for those requests that don't have a session.
(This is done by ``CsrfResponseMiddleware``).
2. On all incoming POST requests that have the session cookie set, it
checks that the 'csrfmiddlewaretoken' is present and correct. If it
isn't, the user will get a 403 error. (This is done by
``CsrfViewMiddleware``)
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.
POST requests that are not accompanied by a session cookie are not protected,
but they do not need to be protected, since the 'attacking' Web site
could make these kind of requests anyway.
The Content-Type is checked before modifying the response, and only
pages that are served as 'text/html' or 'application/xml+xhtml'
are modified.
The middleware tries to be smart about requests that come in via AJAX. Many
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``. (Note that this is not secure if you
don't trust content within the same domain or subdomains.)
.. _9.1.1 Safe Methods, HTTP 1.1, RFC 2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Limitations
===========
These middleware require Django's session framework to work. If you
have a custom authentication system that manually sets cookies and the
like, it won't help you.
If 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. It may still be possible
to use the middleware, provided you can find some way to get the
CSRF token and ensure that is included when your form is submitted.