mirror of
https://github.com/django/django.git
synced 2024-12-25 02:26:12 +00:00
9a2e338107
This commit also decomposes the decorator into two decorators which can be used separately, adds some tests, updates docs and fixes some code comments. git-svn-id: http://code.djangoproject.com/svn/django/trunk@9815 bcc190cf-cafb-0310-a4f2-bffc1f526a37
125 lines
5.2 KiB
Plaintext
125 lines
5.2 KiB
Plaintext
.. _ref-contrib-csrf:
|
|
|
|
=====================================
|
|
Cross Site Request Forgery protection
|
|
=====================================
|
|
|
|
.. module:: django.contrib.csrf
|
|
:synopsis: Protects against Cross Site Request Forgeries
|
|
|
|
The CsrfMiddleware class 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 this
|
|
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.CsrfMiddleware'`` to
|
|
your list of middleware classes, :setting:`MIDDLEWARE_CLASSES`. It 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 is actually composed of two middleware:
|
|
``CsrfViewMiddleware`` which performs the checks on incoming requests,
|
|
and ``CsrfResponseMiddleware`` which performs post-processing of the
|
|
result. This allows the individual components to be used and/or
|
|
replaced instead of using ``CsrfMiddleware``.
|
|
|
|
.. 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 the
|
|
CsrfMiddleware, 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 itself, 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
|
|
============
|
|
|
|
CsrfMiddleware does 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
|
|
===========
|
|
|
|
CsrfMiddleware requires 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.
|