mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	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.
 |