| 1 |
===================================== |
|---|
| 2 |
Cross Site Request Forgery Protection |
|---|
| 3 |
===================================== |
|---|
| 4 |
|
|---|
| 5 |
The CsrfMiddleware class provides easy-to-use protection against |
|---|
| 6 |
`Cross Site Request Forgeries`_. This type of attack occurs when a malicious |
|---|
| 7 |
web site creates a link or form button that is intended to perform some action |
|---|
| 8 |
on your web site, using the credentials of a logged-in user who is tricked |
|---|
| 9 |
into clicking on the link in their browser. |
|---|
| 10 |
|
|---|
| 11 |
The first defense against CSRF attacks is to ensure that GET requests |
|---|
| 12 |
are side-effect free. POST requests can then be protected by adding this |
|---|
| 13 |
middleware into your list of installed middleware. |
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
.. _Cross Site Request Forgeries: http://www.squarefree.com/securitytips/web-developers.html#CSRF |
|---|
| 17 |
|
|---|
| 18 |
How to use it |
|---|
| 19 |
============= |
|---|
| 20 |
Add the middleware ``'django.contrib.csrf.middleware.CsrfMiddleware'`` to |
|---|
| 21 |
your list of middleware classes, ``MIDDLEWARE_CLASSES``. It needs to process |
|---|
| 22 |
the response after the SessionMiddleware, so must come before it in the |
|---|
| 23 |
list. It also must process the response before things like compression |
|---|
| 24 |
happen to the response, so it must come after GZipMiddleware in the list. |
|---|
| 25 |
|
|---|
| 26 |
How it works |
|---|
| 27 |
============ |
|---|
| 28 |
CsrfMiddleware does two things: |
|---|
| 29 |
|
|---|
| 30 |
1. It modifies outgoing requests by adding a hidden form field to all |
|---|
| 31 |
'POST' forms, with the name 'csrfmiddlewaretoken' and a value which is |
|---|
| 32 |
a hash of the session ID plus a secret. If there is no session ID set, |
|---|
| 33 |
this modification of the response isn't done, so there is very little |
|---|
| 34 |
performance penalty for those requests that don't have a session. |
|---|
| 35 |
|
|---|
| 36 |
2. On all incoming POST requests that have the session cookie set, it |
|---|
| 37 |
checks that the 'csrfmiddlewaretoken' is present and correct. If it |
|---|
| 38 |
isn't, the user will get a 403 error. |
|---|
| 39 |
|
|---|
| 40 |
This ensures that only forms that have originated from your web site |
|---|
| 41 |
can be used to POST data back. |
|---|
| 42 |
|
|---|
| 43 |
It deliberately only targets HTTP POST requests (and the corresponding |
|---|
| 44 |
POST forms). GET requests ought never to have side effects (if you are |
|---|
| 45 |
using HTTP GET and POST correctly), and so a CSRF attack with a GET |
|---|
| 46 |
request will always be harmless. |
|---|
| 47 |
|
|---|
| 48 |
POST requests that are not accompanied by a session cookie are not protected, |
|---|
| 49 |
but they do not need to be protected, since the 'attacking' web site |
|---|
| 50 |
could make these kind of requests anyway. |
|---|
| 51 |
|
|---|
| 52 |
The Content-Type is checked before modifying the response, and only |
|---|
| 53 |
pages that are served as 'text/html' or 'application/xml+xhtml' |
|---|
| 54 |
are modified. |
|---|
| 55 |
|
|---|
| 56 |
Limitations |
|---|
| 57 |
=========== |
|---|
| 58 |
CsrfMiddleware requires Django's session framework to work. If you have |
|---|
| 59 |
a custom authentication system that manually sets cookies and the like, |
|---|
| 60 |
it won't help you. |
|---|
| 61 |
|
|---|
| 62 |
If your app creates HTML pages and forms in some unusual way, (e.g. |
|---|
| 63 |
it sends fragments of HTML in javascript document.write statements) |
|---|
| 64 |
you might bypass the filter that adds the hidden field to the form, |
|---|
| 65 |
in which case form submission will always fail. It may still be possible |
|---|
| 66 |
to use the middleware, provided you can find some way to get the |
|---|
| 67 |
CSRF token and ensure that is included when your form is submitted. |
|---|