Ticket #9977: csrf_template_tag_4.diff
File csrf_template_tag_4.diff, 35.4 KB (added by , 16 years ago) |
---|
-
django/conf/project_template/settings.py
60 60 MIDDLEWARE_CLASSES = ( 61 61 'django.middleware.common.CommonMiddleware', 62 62 'django.contrib.csrf.middleware.CsrfViewMiddleware', 63 'django.contrib.csrf.middleware.CsrfResponseMiddleware',64 63 'django.contrib.sessions.middleware.SessionMiddleware', 65 64 'django.contrib.auth.middleware.AuthenticationMiddleware', 66 65 ) … … 76 75 INSTALLED_APPS = ( 77 76 'django.contrib.auth', 78 77 'django.contrib.contenttypes', 78 'django.contrib.csrf', 79 79 'django.contrib.sessions', 80 80 'django.contrib.sites', 81 81 ) -
django/conf/global_settings.py
165 165 'django.core.context_processors.debug', 166 166 'django.core.context_processors.i18n', 167 167 'django.core.context_processors.media', 168 'django.contrib.csrf.context_processors.csrf', 168 169 # 'django.core.context_processors.request', 169 170 ) 170 171 … … 303 304 MIDDLEWARE_CLASSES = ( 304 305 # 'django.middleware.gzip.GZipMiddleware', 305 306 'django.contrib.csrf.middleware.CsrfViewMiddleware', 306 'django.contrib.csrf.middleware.CsrfResponseMiddleware',307 307 'django.contrib.sessions.middleware.SessionMiddleware', 308 308 'django.contrib.auth.middleware.AuthenticationMiddleware', 309 309 # 'django.middleware.http.ConditionalGetMiddleware', … … 379 379 # The number of days a password reset link is valid for 380 380 PASSWORD_RESET_TIMEOUT_DAYS = 3 381 381 382 ######## 383 # CSRF # 384 ######## 385 386 # Dotted path to callable to be used as view when a request is 387 # rejected by the CSRF middleware. 388 CSRF_FAILURE_VIEW = 'django.contrib.csrf.views.csrf_failure' 389 382 390 ########### 383 391 # TESTING # 384 392 ########### -
django/contrib/formtools/templates/formtools/preview.html
1 1 {% extends "base.html" %} 2 2 {% load csrf %} 3 3 {% block content %} 4 4 5 5 <h1>Preview your submission</h1> … … 15 15 16 16 <p>Security hash: {{ hash_value }}</p> 17 17 18 <form action="" method="post"> 18 <form action="" method="post">{% csrf_token %} 19 19 {% for field in form %}{{ field.as_hidden }} 20 20 {% endfor %} 21 21 <input type="hidden" name="{{ stage_field }}" value="2" /> … … 25 25 26 26 <h1>Or edit it again</h1> 27 27 28 <form action="" method="post"> 28 <form action="" method="post">{% csrf_token %} 29 29 <table> 30 30 {{ form }} 31 31 </table> -
django/contrib/formtools/templates/formtools/form.html
1 1 {% extends "base.html" %} 2 2 {% load csrf %} 3 3 {% block content %} 4 4 5 5 {% if form.errors %}<h1>Please correct the following errors</h1>{% else %}<h1>Submit</h1>{% endif %} 6 6 7 <form action="" method="post"> 7 <form action="" method="post">{% csrf_token %} 8 8 <table> 9 9 {{ form }} 10 10 </table> -
django/contrib/comments/templates/comments/approve.html
1 1 {% extends "comments/base.html" %} 2 {% load i18n %}2 {% load i18n csrf %} 3 3 4 4 {% block title %}{% trans "Approve a comment" %}{% endblock %} 5 5 6 6 {% block content %} 7 7 <h1>{% trans "Really make this comment public?" %}</h1> 8 8 <blockquote>{{ comment|linebreaks }}</blockquote> 9 <form action="." method="post"> 9 <form action="." method="post">{% csrf_token %} 10 10 <input type="hidden" name="next" value="{{ next }}" id="next" /> 11 11 <p class="submit"> 12 12 <input type="submit" name="submit" value="{% trans "Approve" %}" /> or <a href="{{ comment.get_absolute_url }}">cancel</a> -
django/contrib/comments/templates/comments/preview.html
1 1 {% extends "comments/base.html" %} 2 {% load i18n %}2 {% load i18n csrf %} 3 3 4 4 {% block title %}{% trans "Preview your comment" %}{% endblock %} 5 5 6 6 {% block content %} 7 7 {% load comments %} 8 <form action="{% comment_form_target %}" method="post"> 8 <form action="{% comment_form_target %}" method="post">{% csrf_token %} 9 9 {% if form.errors %} 10 10 <h1>{% blocktrans count form.errors|length as counter %}Please correct the error below{% plural %}Please correct the errors below{% endblocktrans %}</h1> 11 11 {% else %} -
django/contrib/comments/templates/comments/delete.html
1 1 {% extends "comments/base.html" %} 2 {% load i18n %}2 {% load i18n csrf %} 3 3 4 4 {% block title %}{% trans "Remove a comment" %}{% endblock %} 5 5 6 6 {% block content %} 7 7 <h1>{% trans "Really remove this comment?" %}</h1> 8 8 <blockquote>{{ comment|linebreaks }}</blockquote> 9 <form action="." method="post"> 9 <form action="." method="post">{% csrf_token %} 10 10 <input type="hidden" name="next" value="{{ next }}" id="next" /> 11 11 <p class="submit"> 12 12 <input type="submit" name="submit" value="{% trans "Remove" %}" /> or <a href="{{ comment.get_absolute_url }}">cancel</a> -
django/contrib/comments/templates/comments/form.html
1 {% load comments i18n %}2 <form action="{% comment_form_target %}" method="post"> 1 {% load comments i18n csrf %} 2 <form action="{% comment_form_target %}" method="post">{% csrf_token %} 3 3 {% for field in form %} 4 4 {% if field.is_hidden %} 5 5 {{ field }} -
django/contrib/comments/templates/comments/moderation_queue.html
1 1 {% extends "admin/change_list.html" %} 2 {% load adminmedia i18n %}2 {% load adminmedia i18n csrf %} 3 3 4 4 {% block title %}{% trans "Comment moderation queue" %}{% endblock %} 5 5 … … 44 44 {% for comment in comments %} 45 45 <tr class="{% cycle 'row1' 'row2' %}"> 46 46 <td class="actions"> 47 <form action="{% url comments-approve comment.pk %}" method="post"> 47 <form action="{% url comments-approve comment.pk %}" method="post">{% csrf_token %} 48 48 <input type="hidden" name="next" value="{% url comments-moderation-queue %}" /> 49 49 <input class="approve submit" type="submit" name="submit" value="{% trans "Approve" %}" /> 50 50 </form> 51 <form action="{% url comments-delete comment.pk %}" method="post"> 51 <form action="{% url comments-delete comment.pk %}" method="post">{% csrf_token %} 52 52 <input type="hidden" name="next" value="{% url comments-moderation-queue %}" /> 53 53 <input class="remove submit" type="submit" name="submit" value="{% trans "Remove" %}" /> 54 54 </form> -
django/contrib/comments/templates/comments/flag.html
1 1 {% extends "comments/base.html" %} 2 {% load i18n %}2 {% load i18n csrf %} 3 3 4 4 {% block title %}{% trans "Flag this comment" %}{% endblock %} 5 5 6 6 {% block content %} 7 7 <h1>{% trans "Really flag this comment?" %}</h1> 8 8 <blockquote>{{ comment|linebreaks }}</blockquote> 9 <form action="." method="post"> 9 <form action="." method="post">{% csrf_token %} 10 10 <input type="hidden" name="next" value="{{ next }}" id="next" /> 11 11 <p class="submit"> 12 12 <input type="submit" name="submit" value="{% trans "Flag" %}" /> or <a href="{{ comment.get_absolute_url }}">cancel</a> -
django/contrib/admin/templates/admin/change_list.html
1 1 {% extends "admin/base_site.html" %} 2 {% load adminmedia admin_list i18n %}2 {% load adminmedia admin_list i18n csrf %} 3 3 4 4 {% block extrastyle %} 5 5 {{ block.super }} … … 64 64 {% endblock %} 65 65 66 66 {% if cl.formset %} 67 <form action="" method="post"{% if cl.formset.is_multipart %} enctype="multipart/form-data"{% endif %}> 67 <form action="" method="post"{% if cl.formset.is_multipart %} enctype="multipart/form-data"{% endif %}>{% csrf_token %} 68 68 {{ cl.formset.management_form }} 69 69 {% endif %} 70 70 -
django/contrib/admin/templates/admin/template_validator.html
1 1 {% extends "admin/base_site.html" %} 2 2 {% load csrf %} 3 3 {% block content %} 4 4 5 5 <div id="content-main"> 6 6 7 <form action="" method="post"> 7 <form action="" method="post">{% csrf_token %} 8 8 9 9 {% if form.errors %} 10 10 <p class="errornote">Your template had {{ form.errors|length }} error{{ form.errors|pluralize }}:</p> -
django/contrib/admin/templates/admin/auth/user/change_password.html
1 1 {% extends "admin/base_site.html" %} 2 {% load i18n admin_modify adminmedia %}2 {% load i18n admin_modify adminmedia csrf %} 3 3 {% block extrahead %}{{ block.super }} 4 4 <script type="text/javascript" src="../../../../jsi18n/"></script> 5 5 {% endblock %} … … 14 14 </div> 15 15 {% endif %}{% endblock %} 16 16 {% block content %}<div id="content-main"> 17 <form action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% block form_top %}{% endblock %}17 <form action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% csrf_token %}{% block form_top %}{% endblock %} 18 18 <div> 19 19 {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %} 20 20 {% if form.errors %} -
django/contrib/admin/templates/admin/login.html
1 1 {% extends "admin/base_site.html" %} 2 {% load i18n %}2 {% load i18n csrf %} 3 3 4 4 {% block extrastyle %}{% load adminmedia %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/login.css" />{% endblock %} 5 5 … … 14 14 <p class="errornote">{{ error_message }}</p> 15 15 {% endif %} 16 16 <div id="content-main"> 17 <form action="{{ app_path }}" method="post" id="login-form"> 17 <form action="{{ app_path }}" method="post" id="login-form">{% csrf_token %} 18 18 <div class="form-row"> 19 19 <label for="id_username">{% trans 'Username:' %}</label> <input type="text" name="username" id="id_username" /> 20 20 </div> -
django/contrib/admin/templates/admin/change_form.html
1 1 {% extends "admin/base_site.html" %} 2 {% load i18n admin_modify adminmedia %}2 {% load i18n admin_modify adminmedia csrf %} 3 3 4 4 {% block extrahead %}{{ block.super }} 5 5 <script type="text/javascript" src="../../../jsi18n/"></script> … … 29 29 </ul> 30 30 {% endif %}{% endif %} 31 31 {% endblock %} 32 <form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% block form_top %}{% endblock %}32 <form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% csrf_token %}{% block form_top %}{% endblock %} 33 33 <div> 34 34 {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %} 35 35 {% if save_on_top %}{% submit_row %}{% endif %} -
django/contrib/admin/templates/admin/delete_confirmation.html
1 1 {% extends "admin/base_site.html" %} 2 {% load i18n %}2 {% load i18n csrf %} 3 3 4 4 {% block breadcrumbs %} 5 5 <div class="breadcrumbs"> … … 22 22 {% else %} 23 23 <p>{% blocktrans with object as escaped_object %}Are you sure you want to delete the {{ object_name }} "{{ escaped_object }}"? All of the following related items will be deleted:{% endblocktrans %}</p> 24 24 <ul>{{ deleted_objects|unordered_list }}</ul> 25 <form action="" method="post"> 25 <form action="" method="post">{% csrf_token %} 26 26 <div> 27 27 <input type="hidden" name="post" value="yes" /> 28 28 <input type="submit" value="{% trans "Yes, I'm sure" %}" /> -
django/contrib/admin/templates/registration/password_reset_confirm.html
1 1 {% extends "admin/base_site.html" %} 2 {% load i18n %}2 {% load i18n csrf %} 3 3 4 4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> › {% trans 'Password reset confirmation' %}</div>{% endblock %} 5 5 … … 13 13 14 14 <p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p> 15 15 16 <form action="" method="post"> 16 <form action="" method="post">{% csrf_token %} 17 17 {{ form.new_password1.errors }} 18 18 <p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p> 19 19 {{ form.new_password2.errors }} -
django/contrib/admin/templates/registration/password_reset_form.html
1 1 {% extends "admin/base_site.html" %} 2 {% load i18n %}2 {% load i18n csrf %} 3 3 4 4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> › {% trans 'Password reset' %}</div>{% endblock %} 5 5 … … 11 11 12 12 <p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}</p> 13 13 14 <form action="" method="post"> 14 <form action="" method="post">{% csrf_token %} 15 15 {{ form.email.errors }} 16 16 <p><label for="id_email">{% trans 'E-mail address:' %}</label> {{ form.email }} <input type="submit" value="{% trans 'Reset my password' %}" /></p> 17 17 </form> -
django/contrib/admin/templates/registration/password_change_form.html
1 1 {% extends "admin/base_site.html" %} 2 {% load i18n %}2 {% load i18n csrf %} 3 3 {% block userlinks %}{% url django-admindocs-docroot as docsroot %}{% if docsroot %}<a href="{{ docsroot }}">{% trans 'Documentation' %}</a> / {% endif %} {% trans 'Change password' %} / <a href="../logout/">{% trans 'Log out' %}</a>{% endblock %} 4 4 {% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> › {% trans 'Password change' %}</div>{% endblock %} 5 5 … … 11 11 12 12 <p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p> 13 13 14 <form action="" method="post"> 14 <form action="" method="post">{% csrf_token %} 15 15 16 16 {{ form.old_password.errors }} 17 17 <p class="aligned wide"><label for="id_old_password">{% trans 'Old password:' %}</label>{{ form.old_password }}</p> -
django/contrib/csrf/middleware.py
13 13 from django.utils.functional import wraps # Python 2.3, 2.4 fallback. 14 14 15 15 from django.conf import settings 16 from django. http import HttpResponseForbidden16 from django.core.urlresolvers import get_callable 17 17 from django.utils.hashcompat import md5_constructor 18 18 from django.utils.safestring import mark_safe 19 19 20 _ERROR_MSG = mark_safe('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><body><h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p></body></html>')21 22 20 _POST_FORM_RE = \ 23 21 re.compile(r'(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE) 24 22 25 23 _HTML_TYPES = ('text/html', 'application/xhtml+xml') 26 24 25 def _get_failure_view(): 26 """ 27 Returns the view to be used for CSRF rejections 28 """ 29 return get_callable(settings.CSRF_FAILURE_VIEW) 30 31 def get_token(request): 32 """ 33 Returns the the CSRF token required for a session, 34 or None if there is no session active. 35 """ 36 try: 37 session_id = request.COOKIES[settings.SESSION_COOKIE_NAME] 38 except KeyError: 39 # No session 40 return None 41 42 return _make_token(session_id) 43 27 44 def _make_token(session_id): 28 45 return md5_constructor(settings.SECRET_KEY + session_id).hexdigest() 29 46 … … 40 57 if request.is_ajax(): 41 58 return None 42 59 43 try: 44 session_id = request.COOKIES[settings.SESSION_COOKIE_NAME] 45 except KeyError: 60 csrf_token = get_token(request) 61 if csrf_token is None: 46 62 # No session, no check required 47 63 return None 48 64 49 csrf_token = _make_token(session_id)50 65 # check incoming token 51 66 try: 52 67 request_csrf_token = request.POST['csrfmiddlewaretoken'] 53 68 except KeyError: 54 return HttpResponseForbidden(_ERROR_MSG)69 return _get_failure_view()(request) 55 70 56 71 if request_csrf_token != csrf_token: 57 return HttpResponseForbidden(_ERROR_MSG)72 return _get_failure_view()(request) 58 73 59 74 return None 60 75 -
django/contrib/csrf/views.py
1 from django.http import HttpResponseForbidden 2 from django.utils.safestring import mark_safe 3 4 _ERROR_MSG = mark_safe('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><body><h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p></body></html>') 5 6 def csrf_failure(request): 7 """ 8 Default view used when request fails CSRF protection 9 """ 10 return HttpResponseForbidden(_ERROR_MSG) -
django/contrib/csrf/tests.py
Property changes on: django/contrib/csrf/views.py ___________________________________________________________________ Added: svn:eol-style + native
3 3 from django.test import TestCase 4 4 from django.http import HttpRequest, HttpResponse, HttpResponseForbidden 5 5 from django.contrib.csrf.middleware import CsrfMiddleware, _make_token, csrf_exempt 6 from django.contrib.csrf.context_processors import csrf 6 7 from django.conf import settings 8 from django.template import RequestContext, Template 7 9 8 9 10 def post_form_response(): 10 11 resp = HttpResponse(content=""" 11 12 <html><body><form method="POST"><input type="text" /></form></body></html> … … 142 143 req.META['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' 143 144 req2 = CsrfMiddleware().process_view(req, self.get_view(), (), {}) 144 145 self.assertEquals(None, req2) 146 147 def _context_instance(self, req): 148 return RequestContext(req, processors=[csrf]) 149 150 def test_token_node_no_session(self): 151 """ 152 Check that CsrfTokenNode works when no session active 153 """ 154 req = self._get_GET_no_session_request() 155 context = self._context_instance(req) 156 template = Template("{% load csrf %}{% csrf_token %}") 157 self.assertEquals(u"", template.render(context)) 158 159 def test_token_node_no_session(self): 160 """ 161 Check that CsrfTokenNode works when a session is active 162 """ 163 req = self._get_GET_session_request() 164 context = self._context_instance(req) 165 template = Template("{% load csrf %}{% csrf_token %}") 166 rendered = template.render(context) 167 self.assertNotEqual(u"", rendered) 168 expected = ("name='csrfmiddlewaretoken' value='%s'" % _make_token(self._session_id)) 169 self.failUnless(expected in rendered) -
django/contrib/csrf/templatetags/csrf.py
1 from django import template 2 from django.utils.safestring import mark_safe 3 4 register = template.Library() 5 6 class CsrfTokenNode(template.Node): 7 def render(self, context): 8 csrf_token = context.get('csrf_token', None) 9 if csrf_token: 10 if csrf_token == 'NOTNEEDED': 11 return mark_safe(u"") 12 else: 13 return mark_safe(u"<div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='%s' /></div>" % (csrf_token)) 14 else: 15 # It's very probable that the token is missing because of 16 # misconfiguration, so we raise a warning 17 from django.conf import settings 18 if settings.DEBUG: 19 import warnings 20 warnings.warn("A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not having 'django.contrib.csrf.context_processors.csrf' in TEMPLATE_CONTEXT_PROCESSORS.") 21 return u'' 22 23 def csrf_token(parser, token): 24 return CsrfTokenNode() 25 register.tag(csrf_token) -
django/contrib/csrf/context_processors.py
Property changes on: django/contrib/csrf/templatetags/csrf.py ___________________________________________________________________ Added: svn:eol-style + native Property changes on: django/contrib/csrf/templatetags/__init__.py ___________________________________________________________________ Added: svn:eol-style + native
1 from django.contrib.csrf.middleware import get_token 2 3 def csrf(request): 4 """ 5 Context processor that provides a CSRF token, or the string 6 'NOTNEEDED' if it is not needed 7 """ 8 token = get_token(request) 9 if token is None: 10 # In order to be able to provide debugging info in the case of 11 # misconfiguration, we use a sentinel value instead of an empty 12 # dict. 13 return {'csrf_token':'NOTNEEDED'} 14 else: 15 return {'csrf_token': token} 16 -
tests/regressiontests/admin_views/tests.py
Property changes on: django/contrib/csrf/context_processors.py ___________________________________________________________________ Added: svn:eol-style + native
745 745 # 2 management hidden fields = 2 746 746 # main form submit button = 1 747 747 # search field and search submit button = 2 748 # 6 + 2 + 1 + 2 = 11 inputs 749 self.failUnlessEqual(response.content.count("<input"), 11) 748 # csrf hidden field = 1 749 # 6 + 2 + 1 + 2 + 1 = 12 inputs 750 self.failUnlessEqual(response.content.count("<input"), 12) 750 751 # 1 select per object = 3 selects 751 752 self.failUnlessEqual(response.content.count("<select"), 3) 752 753 -
tests/runtests.py
30 30 'django.contrib.sessions', 31 31 'django.contrib.comments', 32 32 'django.contrib.admin', 33 'django.contrib.csrf', 33 34 ] 34 35 35 36 def get_test_models(): -
docs/ref/contrib/csrf.txt
7 7 .. module:: django.contrib.csrf 8 8 :synopsis: Protects against Cross Site Request Forgeries 9 9 10 The C srfMiddleware classes provides easy-to-use protection against11 `Cross Site Request Forgeries`_. This type of attack occurs when a 12 malicious Web site creates a link or form button that is intended to 13 perform some action on your Web site, using the credentials of a 14 logged-in user who is tricked into clicking on the link in their 15 browser.10 The CSRF middleware and template tag provides easy-to-use protection 11 against `Cross Site Request Forgeries`_. This type of attack occurs 12 when a malicious Web site creates a link or form button that is 13 intended to perform some action on your Web site, using the 14 credentials of a logged-in user who is tricked into clicking on the 15 link in their browser. 16 16 17 17 The first defense against CSRF attacks is to ensure that GET requests 18 18 are side-effect free. POST requests can then be protected by adding 19 these middleware into your list of installed middleware. 19 these middleware into your list of installed middleware following the 20 steps below. 20 21 22 .. versionadded:: 1.1 23 The functionality described here is depended on by the 'contrib' 24 apps, including the admin, so usage steps 1, 2 and 4.1.1 below are 25 **required** for these apps to function. 26 21 27 .. _Cross Site Request Forgeries: http://www.squarefree.com/securitytips/web-developers.html#CSRF 22 28 23 29 How to use it 24 30 ============= 31 .. versionchanged:: 1.1 32 The template tag functionality (the recommended way to use this) 33 was added in version 1.1. The previous method (still available) is 34 described under 'Legacy method'. 25 35 26 Add the middleware 27 ``'django.contrib.csrf.middleware.CsrfViewMiddleware'`` and 28 ``'django.contrib.csrf.middleware.CsrfResponseMiddleware'`` to your 29 list of middleware classes, 30 :setting:`MIDDLEWARE_CLASSES`. ``CsrfResponseMiddleware`` needs to 31 process the response after the ``SessionMiddleware``, so must come 32 before it in the list. It also must process the response before 33 things like compression happen to the response, so it must come after 34 ``GZipMiddleware`` in the list. 36 Follow these steps: 35 37 36 The ``CsrfMiddleware`` class, which combines the two classes, is also 37 available, for backwards compatibility with Django 1.0. 38 1. Add the middleware 39 ``'django.contrib.csrf.middleware.CsrfViewMiddleware'`` to your 40 list of middleware classes, :setting:`MIDDLEWARE_CLASSES`. 38 41 39 .. versionchanged:: 1.1 40 previous versions of Django did not provide these two components 41 of ``CsrfMiddleware`` as described above. 42 2. Add ``'django.contrib.csrf'`` to your :setting:`INSTALLED_APPS`. 42 43 44 3. In any template that uses a POST form, first load the 'csrf' 45 template tag library:: 46 47 {% load csrf %} 48 49 Then use the ``csrf_token`` tag inside the ``<form>`` element, e.g.:: 50 51 <form action="" method="POST">{% csrf_token %} 52 53 4. In the corresponding view functions, ensure that the 54 ``'django.contrib.csrf.context_processors.csrf'`` is being 55 used. Usually, this can be done in one of two ways: 56 57 1. Using RequestContext: 58 59 1. Ensure ``'django.contrib.csrf.context_processors.csrf'`` 60 is present in your :setting:`TEMPLATE_CONTEXT_PROCESSORS` 61 setting. It is present by default. 62 63 2. Use ``RequestContext`` as the context instance in the 64 relevant views. If you are using generic views or contrib 65 apps, you are covered already. 66 67 2. Manually import and use the processor to generate the CSRF 68 token and add it to the template context. e.g.:: 69 70 from django.contrib.csrf.context_processors import csrf 71 from django.template import Context 72 from django.shortcuts import render_to_response 73 def my_view(request): 74 c = Context() 75 c.update(csrf(request)) 76 return render_to_response("a_template.html", context_instance=c) 77 78 5. Ensure that any views which create a new session do not in the 79 same response present a POST form. Often this is achieved by 80 doing a redirect. 81 82 The reason for this is as follows: the CSRF 83 token that is inserted by the ``csrf_token`` tag is calculated 84 on the basis of the ID of an existing session (which is known 85 from the cookies attached to the request). When a new session 86 is created, only the outgoing response object is affected, 87 which the template tag does not have access to, so the template 88 tag would produce an incorrect token in this case, resulting in 89 an error when the user tries to submit the form. 90 91 Legacy method 92 ------------- 93 94 In Django 1.0, the template tag did not exist. Instead, a 95 post-processing middleware that re-wrote POST forms to include the 96 CRSF token was used. This is still available as 97 ``CsrfResponseMiddleware``, and it can be used by following these 98 steps: 99 100 1. Follow step 1 above to install ``CsrfViewMiddleware``. 101 102 2. Add ``'django.contrib.csrf.middleware.CsrfResponseMiddleware'`` 103 to your :setting:`MIDDLEWARE_CLASSES` setting. 104 105 ``CsrfResponseMiddleware`` needs to process the response after 106 the ``SessionMiddleware``, so must come before it in the list. 107 It also must process the response before things like 108 compression happen to the response, so it must come after 109 ``GZipMiddleware`` in the list. 110 111 Use of the ``CsrfResponseMiddleware`` is not recommended, but it can 112 be used as an interim measure until applications have been updated to use 113 the ``{% crsf_token %}`` tag. 114 115 Django 1.0 provided a single ``CsrfMiddleware`` class. This is also 116 still available for backwards compatibility. It combines the 117 functions of the two new middleware. 118 119 43 120 Exceptions 44 121 ---------- 45 122 … … 66 143 request sent with "X-Requested-With: XMLHttpRequest" is automatically 67 144 exempt. (See the next section.) 68 145 146 Rejected requests 147 ================= 148 149 By default, when an incoming request fails the checks that 150 ``CsrfViewMiddleware`` performs, a '403 Forbidden' response is sent to 151 the user. This should only be seen usually when there is a genuine 152 Cross Site Request Forgery, or when due to a programmer error the CSRF 153 token has not been included with a POST form. 154 155 No logging is done, and the error message is not very friendly, so you 156 may want to provide your own page for handling this condition. To do 157 this, simply set the :setting:`CSRF_FAILURE_VIEW` setting to a dotted 158 path to your own view function. 159 69 160 How it works 70 161 ============ 71 162 72 The CSRF middleware dotwo things:163 The CSRF protection requires two things: 73 164 74 1. It modifies outgoing requests by adding a hidden form field to all75 'POST' forms, with the name 'csrfmiddlewaretoken' and a value which is76 a hash of the session ID plus a secret. If there is no session ID set,77 this modification of the response isn't done, so there is very little78 performance penalty for those requests that don't have a session.79 (This is done by ``CsrfResponseMiddleware``).165 1. A hidden form field with the name 'csrfmiddlewaretoken' must be 166 added to all outgoing POST forms. The value of this field is a 167 hash of the session ID plus a secret. If there is no session ID 168 set, this modification of the response isn't done, so there is very 169 little performance penalty for those requests that don't have a 170 session. 80 171 81 2. On all incoming POST requests that have the session cookie set, it 82 checks that the 'csrfmiddlewaretoken' is present and correct. If it 83 isn't, the user will get a 403 error. (This is done by 84 ``CsrfViewMiddleware``) 172 This part is done by the template tag (and with the 173 legacy method, it is done by ``CsrfResponseMiddleware``). 85 174 175 2. On all incoming POST requests that have the session cookie set, the 176 'csrfmiddlewaretoken' must be present and correct. If it isn't, the 177 user will get a 403 error. 178 179 This check is done by ``CsrfViewMiddleware``. 180 86 181 This ensures that only forms that have originated from your Web site 87 182 can be used to POST data back. 88 183 … … 117 212 have a custom authentication system that manually sets cookies and the 118 213 like, it won't help you. 119 214 120 If your app creates HTML pages and forms in some unusual way, (e.g. 121 it sends fragments of HTML in JavaScript document.write statements) 122 you might bypass the filter that adds the hidden field to the form, 123 in which case form submission will always fail. It may still be possible 124 to use the middleware, provided you can find some way to get the 125 CSRF token and ensure that is included when your form is submitted. 215 If you are using ``CsrfResponseMiddleware`` and your app creates HTML 216 pages and forms in some unusual way, (e.g. it sends fragments of HTML 217 in JavaScript document.write statements) you might bypass the filter 218 that adds the hidden field to the form, in which case form submission 219 will always fail. It may still be possible to use the middleware, 220 provided you can find some way to get the CSRF token and ensure that 221 is included when your form is submitted. -
docs/ref/settings.txt
146 146 147 147 .. setting:: DATABASE_ENGINE 148 148 149 CSRF_FAILURE_VIEW 150 ----------------- 151 152 Default: ``'django.contrib.csrf.views.csrf_failure'`` 153 154 The name of the view function to be used when an incoming request 155 is rejected by the CSRF protection. See :ref:`ref-contrib-csrf`. 156 149 157 DATABASE_ENGINE 150 158 --------------- 151 159