Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added CsrfMiddleware to contrib, and documentation.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@2868 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 8eecb95ec8824f8e6ce89fa7a96e094db906a0f5 1 parent f0141f1
@spookylukey spookylukey authored
View
0  django/contrib/csrf/__init__.py
No changes.
View
84 django/contrib/csrf/middleware.py
@@ -0,0 +1,84 @@
+"""
+Cross Site Request Forgery Middleware.
+
+This module provides a middleware that implements protection
+against request forgeries from other sites.
+
+"""
+from django.conf import settings
+from django.http import HttpResponseForbidden
+import md5
+import re
+
+_ERROR_MSG = "<h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p>"
+
+_POST_FORM_RE = \
+ re.compile(r'(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE)
+
+_HTML_TYPES = ('text/html', 'application/xhtml+xml')
+
+def _make_token(session_id):
+ return md5.new(settings.SECRET_KEY + session_id).hexdigest()
+
+class CsrfMiddleware(object):
+ """Django middleware that adds protection against Cross Site
+ Request Forgeries by adding hidden form fields to POST forms and
+ checking requests for the correct value.
+
+ In the list of middlewares, SessionMiddleware is required, and must come
+ after this middleware. CsrfMiddleWare must come after compression
+ middleware.
+
+ If a session ID cookie is present, it is hashed with the SECRET_KEY
+ setting to create an authentication token. This token is added to all
+ outgoing POST forms and is expected on all incoming POST requests that
+ have a session ID cookie.
+
+ If you are setting cookies directly, instead of using Django's session
+ framework, this middleware will not work.
+ """
+
+ def process_request(self, request):
+ if request.POST:
+ try:
+ session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
+ except KeyError:
+ # No session, no check required
+ return None
+
+ csrf_token = _make_token(session_id)
+ # check incoming token
+ try:
+ request_csrf_token = request.POST['csrfmiddlewaretoken']
+ except KeyError:
+ return HttpResponseForbidden(_ERROR_MSG)
+
+ if request_csrf_token != csrf_token:
+ return HttpResponseForbidden(_ERROR_MSG)
+
+ return None
+
+ def process_response(self, request, response):
+ csrf_token = None
+ try:
+ cookie = response.cookies[settings.SESSION_COOKIE_NAME]
+ csrf_token = _make_token(cookie.value)
+ except KeyError:
+ # No outgoing cookie to set session, but
+ # a session might already exist.
+ try:
+ session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
+ csrf_token = _make_token(session_id)
+ except KeyError:
+ # no incoming or outgoing cookie
+ pass
+
+ if csrf_token is not None and \
+ response['Content-Type'].split(';')[0] in _HTML_TYPES:
+
+ # Modify any POST forms
+ extra_field = "<div style='display:none;'>" + \
+ "<input type='hidden' name='csrfmiddlewaretoken' value='" + \
+ csrf_token + "' /></div>"
+ response.content = _POST_FORM_RE.sub('\\1' + extra_field, response.content)
+ return response
View
10 docs/add_ons.txt
@@ -57,6 +57,16 @@ See the `syndication documentation`_.
.. _syndication documentation: http://www.djangoproject.com/documentation/syndication/
+csrf
+====
+
+A middleware for preventing Cross Site Request Forgeries
+
+See the `csrf documentation`_.
+
+.. _csrf documentation: http://www.djangoproject.com/documentation/csrf/
+
+
Other add-ons
=============
View
68 docs/csrf.txt
@@ -0,0 +1,68 @@
+=====================================
+Cross Site Request Forgery Protection
+=====================================
+
+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, ``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.
+
+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.
+
+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 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 side effects (if you are
+using HTTP GET and POST correctly), and so a CSRF attack with a GET
+request will always 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.
+
+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.
+
Please sign in to comment.
Something went wrong with that request. Please try again.