Ticket #9977: csrf_template_tag_r11477_3.diff
File csrf_template_tag_r11477_3.diff, 80.1 KB (added by , 15 years ago) |
---|
-
AUTHORS
diff -r 1b4df7524b7c AUTHORS
a b 468 468 Gasper Zejn <zejn@kiberpipa.org> 469 469 Jarek Zgoda <jarek.zgoda@gmail.com> 470 470 Cheng Zhang 471 Glenn 472 bthomas 471 473 472 474 A big THANK YOU goes to: 473 475 -
django/conf/global_settings.py
diff -r 1b4df7524b7c django/conf/global_settings.py
a b 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 … … 300 301 MIDDLEWARE_CLASSES = ( 301 302 'django.middleware.common.CommonMiddleware', 302 303 'django.contrib.sessions.middleware.SessionMiddleware', 304 'django.contrib.csrf.middleware.CsrfViewMiddleware', 303 305 'django.contrib.auth.middleware.AuthenticationMiddleware', 304 306 # 'django.middleware.http.ConditionalGetMiddleware', 305 307 # 'django.middleware.gzip.GZipMiddleware', … … 374 376 # The number of days a password reset link is valid for 375 377 PASSWORD_RESET_TIMEOUT_DAYS = 3 376 378 379 ######## 380 # CSRF # 381 ######## 382 383 # Dotted path to callable to be used as view when a request is 384 # rejected by the CSRF middleware. 385 CSRF_FAILURE_VIEW = 'django.contrib.csrf.views.csrf_failure' 386 387 # Name and domain for CSRF cookie. 388 CSRF_COOKIE_NAME = 'csrftoken' 389 CSRF_COOKIE_DOMAIN = None 390 377 391 ########### 378 392 # TESTING # 379 393 ########### -
django/conf/project_template/settings.py
diff -r 1b4df7524b7c django/conf/project_template/settings.py
a b 60 60 MIDDLEWARE_CLASSES = ( 61 61 'django.middleware.common.CommonMiddleware', 62 62 'django.contrib.sessions.middleware.SessionMiddleware', 63 'django.contrib.csrf.middleware.CsrfViewMiddleware', 63 64 'django.contrib.auth.middleware.AuthenticationMiddleware', 64 65 ) 65 66 … … 74 75 INSTALLED_APPS = ( 75 76 'django.contrib.auth', 76 77 'django.contrib.contenttypes', 78 'django.contrib.csrf', 77 79 'django.contrib.sessions', 78 80 'django.contrib.sites', 79 81 ) -
django/contrib/admin/sites.py
diff -r 1b4df7524b7c django/contrib/admin/sites.py
a b 3 3 from django.contrib.admin import ModelAdmin 4 4 from django.contrib.admin import actions 5 5 from django.contrib.auth import authenticate, login 6 from django.contrib.csrf.middleware import csrf_response_exempt 6 7 from django.db.models.base import ModelBase 7 8 from django.core.exceptions import ImproperlyConfigured 8 9 from django.core.urlresolvers import reverse … … 154 155 raise ImproperlyConfigured("Put 'django.contrib.admin' in your INSTALLED_APPS setting in order to use the admin application.") 155 156 if not ContentType._meta.installed: 156 157 raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in your INSTALLED_APPS setting in order to use the admin application.") 158 if 'django.contrib.csrf' not in settings.INSTALLED_APPS: 159 raise ImproperlyConfigured("Put 'django.contrib.csrf' in your INSTALLED_APPS setting in order to use the admin application.") 157 160 if 'django.core.context_processors.auth' not in settings.TEMPLATE_CONTEXT_PROCESSORS: 158 161 raise ImproperlyConfigured("Put 'django.core.context_processors.auth' in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.") 162 if 'django.contrib.csrf.context_processors.csrf' not in settings.TEMPLATE_CONTEXT_PROCESSORS: 163 raise ImproperlyConfigured("Put 'django.contrib.csrf.context_processors.csrf' in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.") 159 164 160 165 def admin_view(self, view, cacheable=False): 161 166 """ … … 186 191 return view(request, *args, **kwargs) 187 192 if not cacheable: 188 193 inner = never_cache(inner) 194 inner = csrf_response_exempt(inner) 189 195 return update_wrapper(inner, view) 190 196 191 197 def get_urls(self): -
django/contrib/admin/templates/admin/auth/user/change_password.html
diff -r 1b4df7524b7c django/contrib/admin/templates/admin/auth/user/change_password.html
a b 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 %} … … 15 15 </div> 16 16 {% endif %}{% endblock %} 17 17 {% block content %}<div id="content-main"> 18 <form action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% block form_top %}{% endblock %}18 <form action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% csrf_token %}{% block form_top %}{% endblock %} 19 19 <div> 20 20 {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %} 21 21 {% if form.errors %} -
django/contrib/admin/templates/admin/change_form.html
diff -r 1b4df7524b7c django/contrib/admin/templates/admin/change_form.html
a b 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/change_list.html
diff -r 1b4df7524b7c django/contrib/admin/templates/admin/change_list.html
a b 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 }} … … 68 68 {% endif %} 69 69 {% endblock %} 70 70 71 <form action="" method="post"{% if cl.formset.is_multipart %} enctype="multipart/form-data"{% endif %}> 71 <form action="" method="post"{% if cl.formset.is_multipart %} enctype="multipart/form-data"{% endif %}>{% csrf_token %} 72 72 {% if cl.formset %} 73 73 {{ cl.formset.management_form }} 74 74 {% endif %} -
django/contrib/admin/templates/admin/delete_confirmation.html
diff -r 1b4df7524b7c django/contrib/admin/templates/admin/delete_confirmation.html
a b 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/admin/delete_selected_confirmation.html
diff -r 1b4df7524b7c django/contrib/admin/templates/admin/delete_selected_confirmation.html
a b 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"> … … 23 23 {% for deleteable_object in deletable_objects %} 24 24 <ul>{{ deleteable_object|unordered_list }}</ul> 25 25 {% endfor %} 26 <form action="" method="post"> 26 <form action="" method="post">{% csrf_token %} 27 27 <div> 28 28 {% for obj in queryset %} 29 29 <input type="hidden" name="{{ action_checkbox_name }}" value="{{ obj.pk }}" /> -
django/contrib/admin/templates/admin/login.html
diff -r 1b4df7524b7c django/contrib/admin/templates/admin/login.html
a b 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/template_validator.html
diff -r 1b4df7524b7c django/contrib/admin/templates/admin/template_validator.html
a b 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/registration/password_change_form.html
diff -r 1b4df7524b7c django/contrib/admin/templates/registration/password_change_form.html
a b 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/admin/templates/registration/password_reset_confirm.html
diff -r 1b4df7524b7c django/contrib/admin/templates/registration/password_reset_confirm.html
a b 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
diff -r 1b4df7524b7c django/contrib/admin/templates/registration/password_reset_form.html
a b 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/comments/templates/comments/approve.html
diff -r 1b4df7524b7c django/contrib/comments/templates/comments/approve.html
a b 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 {% if next %}<input type="hidden" name="next" value="{{ next }}" id="next" />{% endif %} 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/delete.html
diff -r 1b4df7524b7c django/contrib/comments/templates/comments/delete.html
a b 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 {% if next %}<input type="hidden" name="next" value="{{ next }}" id="next" />{% endif %} 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/flag.html
diff -r 1b4df7524b7c django/contrib/comments/templates/comments/flag.html
a b 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 {% if next %}<input type="hidden" name="next" value="{{ next }}" id="next" />{% endif %} 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/comments/templates/comments/form.html
diff -r 1b4df7524b7c django/contrib/comments/templates/comments/form.html
a b 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 {% if next %}<input type="hidden" name="next" value="{{ next }}" />{% endif %} 4 4 {% for field in form %} 5 5 {% if field.is_hidden %} -
django/contrib/comments/templates/comments/moderation_queue.html
diff -r 1b4df7524b7c django/contrib/comments/templates/comments/moderation_queue.html
a b 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/preview.html
diff -r 1b4df7524b7c django/contrib/comments/templates/comments/preview.html
a b 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 next %}<input type="hidden" name="next" value="{{ next }}" />{% endif %} 10 10 {% if form.errors %} 11 11 <h1>{% blocktrans count form.errors|length as counter %}Please correct the error below{% plural %}Please correct the errors below{% endblocktrans %}</h1> -
new file django/contrib/csrf/context_processors.py
diff -r 1b4df7524b7c django/contrib/csrf/context_processors.py
- + 1 from django.contrib.csrf.middleware import get_token 2 from django.utils.functional import lazy 3 4 def csrf(request): 5 """ 6 Context processor that provides a CSRF token, or the string 7 'NOTNEEDED' if it is not needed 8 """ 9 def _get_val(): 10 token = get_token(request) 11 if token is None: 12 # In order to be able to provide debugging info in the 13 # case of misconfiguration, we use a sentinel value 14 # instead of returning an empty dict. 15 return 'NOTNEEDED' 16 else: 17 return token 18 _get_val = lazy(_get_val, str) 19 20 return {'csrf_token': _get_val() } -
django/contrib/csrf/middleware.py
diff -r 1b4df7524b7c django/contrib/csrf/middleware.py
a b 5 5 against request forgeries from other sites. 6 6 """ 7 7 8 import itertools 8 9 import re 9 import itertools10 import random 10 11 try: 11 12 from functools import wraps 12 13 except ImportError: 13 14 from django.utils.functional import wraps # Python 2.3, 2.4 fallback. 14 15 15 16 from django.conf import settings 16 from django. http import HttpResponseForbidden17 from django.core.urlresolvers import get_callable 17 18 from django.utils.hashcompat import md5_constructor 18 19 from django.utils.safestring import mark_safe 19 20 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 21 _POST_FORM_RE = \ 23 22 re.compile(r'(<form\W[^>]*\bmethod\s*=\s*(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE) 24 23 25 24 _HTML_TYPES = ('text/html', 'application/xhtml+xml') 26 25 27 def _make_token(session_id): 26 # Use the system (hardware-based) random number generator if it exists. 27 if hasattr(random, 'SystemRandom'): 28 randrange = random.SystemRandom().randrange 29 else: 30 randrange = random.randrange 31 _MAX_CSRF_KEY = 18446744073709551616L # 2 << 63 32 33 def _get_failure_view(): 34 """ 35 Returns the view to be used for CSRF rejections 36 """ 37 return get_callable(settings.CSRF_FAILURE_VIEW) 38 39 def _get_new_csrf_key(): 40 return md5_constructor("%s%s" 41 % (randrange(0, _MAX_CSRF_KEY), settings.SECRET_KEY)).hexdigest() 42 43 def _make_legacy_session_token(session_id): 28 44 return md5_constructor(settings.SECRET_KEY + session_id).hexdigest() 29 45 46 def get_token(request): 47 """ 48 Returns the the CSRF token required for a POST form. 49 """ 50 request.META["CSRF_COOKIE_USED"] = True 51 return request.META.get("CSRF_COOKIE", None) 52 30 53 class CsrfViewMiddleware(object): 31 54 """ 32 55 Middleware that requires a present and correct csrfmiddlewaretoken 33 for POST requests that have an active session. 56 for POST requests that have a CSRF cookie, and sets an outgoing 57 CSRF cookie. 58 59 This middleware should be used in conjunction with the csrf_token template 60 tag. 34 61 """ 35 62 def process_view(self, request, callback, callback_args, callback_kwargs): 63 reject = lambda: _get_failure_view()(request) 64 65 if getattr(callback, 'csrf_exempt', False): 66 return None 67 68 # If the user doesn't have a CSRF cookie, generate one and store it in the 69 # request, so it's available to the view. We'll store it in a cookie when 70 # we reach the response. 71 try: 72 request.META["CSRF_COOKIE"] = request.COOKIES[settings.CSRF_COOKIE_NAME] 73 cookie_is_new = False 74 except KeyError: 75 # No cookie, so create one. 76 request.META["CSRF_COOKIE"] = _get_new_csrf_key() 77 cookie_is_new = True 78 36 79 if request.method == 'POST': 37 if getattr(callback, 'csrf_exempt', False):38 return None39 40 80 if request.is_ajax(): 41 81 return None 42 82 43 try:44 session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]45 except KeyError:46 # No session, no check required47 return None83 if request.is_secure(): 84 # Strict referer checking for HTTPS 85 referer = request.META.get('HTTP_REFERER') 86 if referer is None: 87 return reject() 48 88 49 csrf_token = _make_token(session_id) 89 # The following check ensures that the referer is HTTPS, 90 # the domains match and the ports match. This might be too strict. 91 if not referer.startswith('https://%s/' % request.get_host()): 92 return reject() 93 94 # If the user didn't already have a CSRF key, then accept the 95 # session key for the middleware token, so CSRF protection isn't lost 96 # for the period between upgrading to CSRF cookes to the first time 97 # each user comes back to the site to receive one. 98 if cookie_is_new: 99 try: 100 session_id = request.COOKIES[settings.SESSION_COOKIE_NAME] 101 csrf_token = _make_legacy_session_token(session_id) 102 except KeyError: 103 # No CSRF cookie and no session cookie. For POST requests, 104 # we insist on a CSRF cookie, and in this way we can avoid 105 # all CSRF attacks, including login CSRF. 106 return reject() 107 else: 108 csrf_token = request.META["CSRF_COOKIE"] 109 50 110 # check incoming token 51 try: 52 request_csrf_token = request.POST['csrfmiddlewaretoken'] 53 except KeyError: 54 return HttpResponseForbidden(_ERROR_MSG) 55 111 request_csrf_token = request.POST.get('csrfmiddlewaretoken', None) 56 112 if request_csrf_token != csrf_token: 57 return HttpResponseForbidden(_ERROR_MSG)113 return reject() 58 114 59 115 return None 60 116 117 def process_response(self, request, response): 118 # If CSRF_COOKIE is unset, then CsrfViewMiddleware.process_view was 119 # never called, probaby because a request middleware returned a response 120 # (for example, contrib.auth redirecting to a login page). 121 if request.META.get("CSRF_COOKIE") is None: 122 return response 123 124 if not request.META.get("CSRF_COOKIE_USED", False): 125 return response 126 127 # Set the CSRF cookie even if it's already set, so we renew the expiry timer. 128 response.set_cookie(settings.CSRF_COOKIE_NAME, 129 request.META["CSRF_COOKIE"], max_age = 60 * 60 * 24 * 7 * 52, 130 domain=settings.CSRF_COOKIE_DOMAIN) 131 132 return response 133 61 134 class CsrfResponseMiddleware(object): 62 135 """ 63 Middleware that post-processes a response to add a 64 csrfmiddlewaretoken if the response/request have an active 65 session. 136 DEPRECATED 137 Middleware that post-processes a response to add a csrfmiddlewaretoken. 138 139 This exists for backwards compatibility and as an interim measure until 140 applications are converted to using use the csrf_token template tag 141 instead. It will be removed in Django 1.4. 66 142 """ 143 def __init__(self): 144 import warnings 145 warnings.warn( 146 "CsrfResponseMiddleware and CsrfMiddleware are deprecated; use CsrfViewMiddleware and the template tag instead (see CSRF documentation).", 147 PendingDeprecationWarning 148 ) 149 67 150 def process_response(self, request, response): 68 151 if getattr(response, 'csrf_exempt', False): 69 152 return response 70 153 71 csrf_token = None 72 try: 73 # This covers a corner case in which the outgoing response 74 # both contains a form and sets a session cookie. This 75 # really should not be needed, since it is best if views 76 # that create a new session (login pages) also do a 77 # redirect, as is done by all such view functions in 78 # Django. 79 cookie = response.cookies[settings.SESSION_COOKIE_NAME] 80 csrf_token = _make_token(cookie.value) 81 except KeyError: 82 # Normal case - look for existing session cookie 83 try: 84 session_id = request.COOKIES[settings.SESSION_COOKIE_NAME] 85 csrf_token = _make_token(session_id) 86 except KeyError: 87 # no incoming or outgoing cookie 88 pass 89 90 if csrf_token is not None and \ 91 response['Content-Type'].split(';')[0] in _HTML_TYPES: 154 if response['Content-Type'].split(';')[0] in _HTML_TYPES: 155 csrf_token = get_token(request) 156 # If csrf_token is None, we have no token for this request, which probably 157 # means that this is a response from a request middleware. 158 if csrf_token is None: 159 return response 92 160 93 161 # ensure we don't add the 'id' attribute twice (HTML validity) 94 162 idattributes = itertools.chain(("id='csrfmiddlewaretoken'",), 95 163 itertools.repeat('')) 96 164 def add_csrf_field(match): 97 165 """Returns the matched <form> tag plus the added <input> element""" 98 166 return mark_safe(match.group() + "<div style='display:none;'>" + \ … … 104 172 response.content = _POST_FORM_RE.sub(add_csrf_field, response.content) 105 173 return response 106 174 107 class CsrfMiddleware(CsrfViewMiddleware, CsrfResponseMiddleware): 108 """Django middleware that adds protection against Cross Site 175 class CsrfMiddleware(object): 176 """ 177 Django middleware that adds protection against Cross Site 109 178 Request Forgeries by adding hidden form fields to POST forms and 110 179 checking requests for the correct value. 111 180 112 In the list of middlewares, SessionMiddleware is required, and 113 must come after this middleware. CsrfMiddleWare must come after 114 compression middleware. 181 CsrfMiddleware uses two middleware, CsrfViewMiddleware and 182 CsrfResponseMiddleware, which can be used independently. It is recommended 183 to use only CsrfViewMiddleware and use the csrf_token template tag in 184 templates for inserting the token. 185 """ 186 # We can't just inherit from CsrfViewMiddleware and CsrfResponseMiddleware 187 # because both have process_response methods. 188 def __init__(self): 189 self.response_middleware = CsrfResponseMiddleware() 190 self.view_middleware = CsrfViewMiddleware() 115 191 116 If a session ID cookie is present, it is hashed with the 117 SECRET_KEY setting to create an authentication token. This token 118 is added to all outgoing POST forms and is expected on all 119 incoming POST requests that have a session ID cookie. 192 def process_response(self, request, resp): 193 # We must do the response post-processing first, because that calls 194 # get_token(), which triggers a flag saying that the CSRF cookie needs 195 # to be sent (done in CsrfViewMiddleware.process_response) 196 resp2 = self.response_middleware.process_response(request, resp) 197 return self.view_middleware.process_response(request, resp2) 120 198 121 If you are setting cookies directly, instead of using Django's 122 session framework, this middleware will not work. 123 124 CsrfMiddleWare is composed of two middleware, CsrfViewMiddleware 125 and CsrfResponseMiddleware which can be used independently. 126 """ 127 pass 199 def process_view(self, request, callback, callback_args, callback_kwargs): 200 return self.view_middleware.process_view(request, callback, callback_args, 201 callback_kwargs) 128 202 129 203 def csrf_response_exempt(view_func): 130 204 """ -
new file django/contrib/csrf/templatetags/__init__.py
diff -r 1b4df7524b7c django/contrib/csrf/templatetags/__init__.py
- + 1 -
new file django/contrib/csrf/templatetags/csrf.py
diff -r 1b4df7524b7c 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 or not using RequestContext.") 21 return u'' 22 23 def csrf_token(parser, token): 24 return CsrfTokenNode() 25 register.tag(csrf_token) -
django/contrib/csrf/tests.py
diff -r 1b4df7524b7c django/contrib/csrf/tests.py
a b 1 1 # -*- coding: utf-8 -*- 2 2 3 3 from django.test import TestCase 4 from django.http import HttpRequest, HttpResponse, HttpResponseForbidden 5 from django.contrib.csrf.middleware import CsrfMiddleware, _make_token, csrf_exempt 4 from django.http import HttpRequest, HttpResponse 5 from django.contrib.csrf.middleware import CsrfMiddleware, CsrfViewMiddleware, csrf_exempt 6 from django.contrib.csrf.context_processors import csrf 7 from django.contrib.sessions.middleware import SessionMiddleware 8 from django.utils.importlib import import_module 6 9 from django.conf import settings 10 from django.template import RequestContext, Template 7 11 8 12 # Response/views used for CsrfResponseMiddleware and CsrfViewMiddleware tests 9 13 def post_form_response(): 10 14 resp = HttpResponse(content=""" 11 15 <html><body><form method="POST"><input type="text" /></form></body></html> 12 16 """, mimetype="text/html") 13 17 return resp 14 18 15 def test_view(request): 19 def post_form_response_non_html(): 20 resp = post_form_response() 21 resp["Content-Type"] = "application/xml" 22 return resp 23 24 def post_form_view(request): 25 """A view that returns a POST form (without a token)""" 16 26 return post_form_response() 17 27 28 # Response/views used for template tag tests 29 def _token_template(): 30 return Template("{% load csrf %}{% csrf_token %}") 31 32 def _render_csrf_token_template(req): 33 context = RequestContext(req, processors=[csrf]) 34 template = _token_template() 35 return template.render(context) 36 37 def token_view(request): 38 """A view that uses {% csrf_token %}""" 39 return HttpResponse(_render_csrf_token_template(request)) 40 41 def non_token_view_using_request_processor(request): 42 """ 43 A view that doesn't use the token, but does use the csrf view processor. 44 """ 45 context = RequestContext(request, processors=[csrf]) 46 template = Template("{% load csrf %}") 47 return HttpResponse(template.render(context)) 48 49 class TestingHttpRequest(HttpRequest): 50 """ 51 A version of HttpRequest that allows us to change some things 52 more easily 53 """ 54 def is_secure(self): 55 return getattr(self, '_is_secure', False) 56 18 57 class CsrfMiddlewareTest(TestCase): 58 _csrf_id = "1" 19 59 60 # This is a valid session token for this ID and secret key. This was generated using 61 # the old code that we're to be backwards-compatible with. Don't use the CSRF code 62 # to generate this hash, or we're merely testing the code against itself and not 63 # checking backwards-compatibility. This is also the output of (echo -n test1 | md5sum). 64 _session_token = "5a105e8b9d40e1329780d62ea2265d8a" 20 65 _session_id = "1" 66 _secret_key_for_session_test= "test" 21 67 22 def _get_GET_no_ session_request(self):23 return HttpRequest()68 def _get_GET_no_csrf_cookie_request(self): 69 return TestingHttpRequest() 24 70 25 def _get_GET_session_request(self): 26 req = self._get_GET_no_session_request() 71 def _get_GET_csrf_cookie_request(self): 72 req = TestingHttpRequest() 73 req.COOKIES[settings.CSRF_COOKIE_NAME] = self._csrf_id 74 return req 75 76 def _get_POST_csrf_cookie_request(self): 77 req = self._get_GET_csrf_cookie_request() 78 req.method = "POST" 79 return req 80 81 def _get_POST_no_csrf_cookie_request(self): 82 req = self._get_GET_no_csrf_cookie_request() 83 req.method = "POST" 84 return req 85 86 def _get_POST_request_with_token(self): 87 req = self._get_POST_csrf_cookie_request() 88 req.POST['csrfmiddlewaretoken'] = self._csrf_id 89 return req 90 91 def _get_POST_session_request_with_token(self): 92 req = self._get_POST_no_csrf_cookie_request() 93 req.COOKIES[settings.SESSION_COOKIE_NAME] = self._session_id 94 req.POST['csrfmiddlewaretoken'] = self._session_token 95 return req 96 97 def _get_POST_session_request_no_token(self): 98 req = self._get_POST_no_csrf_cookie_request() 27 99 req.COOKIES[settings.SESSION_COOKIE_NAME] = self._session_id 28 100 return req 29 101 30 def _get_POST_session_request(self): 31 req = self._get_GET_session_request() 32 req.method = "POST" 33 return req 102 def _check_token_present(self, response, csrf_id=None): 103 self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % (csrf_id or self._csrf_id)) 34 104 35 def _get_POST_no_session_request(self): 36 req = self._get_GET_no_session_request() 37 req.method = "POST" 38 return req 105 # Check the post processing and outgoing cookie 106 def test_process_response_no_csrf_cookie(self): 107 """ 108 When no prior CSRF cookie exists, check that the cookie is created and a 109 token is inserted. 110 """ 111 req = self._get_GET_no_csrf_cookie_request() 112 CsrfMiddleware().process_view(req, post_form_view, (), {}) 39 113 40 def _get_POST_session_request_with_token(self): 41 req = self._get_POST_session_request() 42 req.POST['csrfmiddlewaretoken'] = _make_token(self._session_id) 43 return req 44 45 def _get_post_form_response(self): 46 return post_form_response() 47 48 def _get_new_session_response(self): 49 resp = self._get_post_form_response() 50 resp.cookies[settings.SESSION_COOKIE_NAME] = self._session_id 51 return resp 52 53 def _check_token_present(self, response): 54 self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % _make_token(self._session_id)) 55 56 def get_view(self): 57 return test_view 58 59 # Check the post processing 60 def test_process_response_no_session(self): 61 """ 62 Check the post-processor does nothing if no session active 63 """ 64 req = self._get_GET_no_session_request() 65 resp = self._get_post_form_response() 114 resp = post_form_response() 66 115 resp_content = resp.content # needed because process_response modifies resp 67 116 resp2 = CsrfMiddleware().process_response(req, resp) 68 self.assertEquals(resp_content, resp2.content)69 117 70 def test_process_response_existing_session(self): 118 csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) 119 self.assertNotEqual(csrf_cookie, False) 120 self.assertNotEqual(resp_content, resp2.content) 121 self._check_token_present(resp2, csrf_cookie.value) 122 123 def test_process_response_no_csrf_cookie_view_only_get_token_used(self): 71 124 """ 72 Check that the token is inserted if there is an existing session 125 When no prior CSRF cookie exists, check that the cookie is created, even 126 if only CsrfViewMiddleware is used. 73 127 """ 74 req = self._get_GET_session_request() 75 resp = self._get_post_form_response() 128 # This is checking that CsrfViewMiddleware has the cookie setting 129 # code. Most of the other tests use CsrfMiddleware. 130 req = self._get_GET_no_csrf_cookie_request() 131 # token_view calls get_token() indirectly 132 CsrfViewMiddleware().process_view(req, token_view, (), {}) 133 resp = token_view(req) 134 resp2 = CsrfViewMiddleware().process_response(req, resp) 135 136 csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) 137 self.assertNotEqual(csrf_cookie, False) 138 139 def test_process_response_get_token_not_used(self): 140 """ 141 Check that if get_token() is not called, the view middleware does not 142 add a cookie. 143 """ 144 # This is important to make pages cacheable. Pages which do call 145 # get_token(), assuming they use the token, are not cacheable because 146 # the token is specific to the user 147 req = self._get_GET_no_csrf_cookie_request() 148 # non_token_view_using_request_processor does not call get_token(), but 149 # does use the csrf request processor. By using this, we are testing 150 # that the view processor is properly lazy and doesn't call get_token() 151 # until needed. 152 CsrfViewMiddleware().process_view(req, non_token_view_using_request_processor, (), {}) 153 resp = non_token_view_using_request_processor(req) 154 resp2 = CsrfViewMiddleware().process_response(req, resp) 155 156 csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False) 157 self.assertEqual(csrf_cookie, False) 158 159 def test_process_response_existing_csrf_cookie(self): 160 """ 161 Check that the token is inserted when a prior CSRF cookie exists 162 """ 163 req = self._get_GET_csrf_cookie_request() 164 CsrfMiddleware().process_view(req, post_form_view, (), {}) 165 166 resp = post_form_response() 76 167 resp_content = resp.content # needed because process_response modifies resp 77 168 resp2 = CsrfMiddleware().process_response(req, resp) 78 169 self.assertNotEqual(resp_content, resp2.content) 79 170 self._check_token_present(resp2) 80 171 81 def test_process_response_n ew_session(self):172 def test_process_response_non_html(self): 82 173 """ 83 Check th at the token is inserted if there is a new session being started174 Check the the post-processor does nothing for content-types not in _HTML_TYPES. 84 175 """ 85 req = self._get_GET_no_session_request() # no session in request 86 resp = self._get_new_session_response() # but new session started 176 req = self._get_GET_no_csrf_cookie_request() 177 CsrfMiddleware().process_view(req, post_form_view, (), {}) 178 resp = post_form_response_non_html() 87 179 resp_content = resp.content # needed because process_response modifies resp 88 180 resp2 = CsrfMiddleware().process_response(req, resp) 89 self.assertNotEqual(resp_content, resp2.content) 90 self._check_token_present(resp2) 181 self.assertEquals(resp_content, resp2.content) 91 182 92 183 def test_process_response_exempt_view(self): 93 184 """ 94 185 Check that no post processing is done for an exempt view 95 186 """ 96 req = self._get_POST_ session_request()97 resp = csrf_exempt( self.get_view())(req)187 req = self._get_POST_csrf_cookie_request() 188 resp = csrf_exempt(post_form_view)(req) 98 189 resp_content = resp.content 99 190 resp2 = CsrfMiddleware().process_response(req, resp) 100 191 self.assertEquals(resp_content, resp2.content) 101 192 102 193 # Check the request processing 103 def test_process_request_no_session (self):194 def test_process_request_no_session_no_csrf_cookie(self): 104 195 """ 105 Check that if n o session is present, the middleware does nothing.106 t o the incoming request.196 Check that if neither a CSRF cookie nor a session cookie are present, 197 the middleware rejects the incoming request. This will stop login CSRF. 107 198 """ 108 req = self._get_POST_no_session_request() 109 req2 = CsrfMiddleware().process_view(req, self.get_view(), (), {}) 199 req = self._get_POST_no_csrf_cookie_request() 200 req2 = CsrfMiddleware().process_view(req, post_form_view, (), {}) 201 self.assertEquals(403, req2.status_code) 202 203 def test_process_request_csrf_cookie_no_token(self): 204 """ 205 Check that if a CSRF cookie is present but no token, the middleware 206 rejects the incoming request. 207 """ 208 req = self._get_POST_csrf_cookie_request() 209 req2 = CsrfMiddleware().process_view(req, post_form_view, (), {}) 210 self.assertEquals(403, req2.status_code) 211 212 def test_process_request_csrf_cookie_and_token(self): 213 """ 214 Check that if both a cookie and a token is present, the middleware lets it through. 215 """ 216 req = self._get_POST_request_with_token() 217 req2 = CsrfMiddleware().process_view(req, post_form_view, (), {}) 110 218 self.assertEquals(None, req2) 111 219 112 def test_process_request_session_ no_token(self):220 def test_process_request_session_cookie_no_csrf_cookie_token(self): 113 221 """ 114 Check that if a session is present but no token, we get a 'forbidden' 222 When no CSRF cookie exists, but the user has a session, check that a token 223 using the session cookie as a legacy CSRF cookie is accepted. 115 224 """ 116 req = self._get_POST_session_request() 117 req2 = CsrfMiddleware().process_view(req, self.get_view(), (), {}) 118 self.assertEquals(HttpResponseForbidden, req2.__class__) 225 orig_secret_key = settings.SECRET_KEY 226 settings.SECRET_KEY = self._secret_key_for_session_test 227 try: 228 req = self._get_POST_session_request_with_token() 229 req2 = CsrfMiddleware().process_view(req, post_form_view, (), {}) 230 self.assertEquals(None, req2) 231 finally: 232 settings.SECRET_KEY = orig_secret_key 119 233 120 def test_process_request_session_ and_token(self):234 def test_process_request_session_cookie_no_csrf_cookie_no_token(self): 121 235 """ 122 Check that if a session is present and a token, the middleware lets it through 236 Check that if a session cookie is present but no token and no CSRF cookie, 237 the request is rejected. 123 238 """ 124 req = self._get_POST_session_request_ with_token()125 req2 = CsrfMiddleware().process_view(req, self.get_view(), (), {})126 self.assertEquals( None, req2)239 req = self._get_POST_session_request_no_token() 240 req2 = CsrfMiddleware().process_view(req, post_form_view, (), {}) 241 self.assertEquals(403, req2.status_code) 127 242 128 def test_process_request_ session_no_token_exempt_view(self):243 def test_process_request_csrf_cookie_no_token_exempt_view(self): 129 244 """ 130 Check that if a sessionis present and no token, but the csrf_exempt245 Check that if a CSRF cookie is present and no token, but the csrf_exempt 131 246 decorator has been applied to the view, the middleware lets it through 132 247 """ 133 req = self._get_POST_ session_request()134 req2 = CsrfMiddleware().process_view(req, csrf_exempt( self.get_view()), (), {})248 req = self._get_POST_csrf_cookie_request() 249 req2 = CsrfMiddleware().process_view(req, csrf_exempt(post_form_view), (), {}) 135 250 self.assertEquals(None, req2) 136 251 137 252 def test_ajax_exemption(self): 138 253 """ 139 254 Check that AJAX requests are automatically exempted. 140 255 """ 141 req = self._get_POST_ session_request()256 req = self._get_POST_csrf_cookie_request() 142 257 req.META['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' 143 req2 = CsrfMiddleware().process_view(req, self.get_view(), (), {})258 req2 = CsrfMiddleware().process_view(req, post_form_view, (), {}) 144 259 self.assertEquals(None, req2) 260 261 # Tests for the template tag method 262 def test_token_node_no_csrf_cookie(self): 263 """ 264 Check that CsrfTokenNode works when no CSRF cookie is set 265 """ 266 req = self._get_GET_no_csrf_cookie_request() 267 resp = token_view(req) 268 self.assertEquals(u"", resp.content) 269 270 def test_token_node_with_csrf_cookie(self): 271 """ 272 Check that CsrfTokenNode works when a CSRF cookie is set 273 """ 274 req = self._get_GET_csrf_cookie_request() 275 CsrfViewMiddleware().process_view(req, token_view, (), {}) 276 resp = token_view(req) 277 self._check_token_present(resp) 278 279 def test_token_node_with_new_csrf_cookie(self): 280 """ 281 Check that CsrfTokenNode works when a CSRF cookie is created by 282 the middleware (when one was not already present) 283 """ 284 req = self._get_GET_no_csrf_cookie_request() 285 CsrfViewMiddleware().process_view(req, token_view, (), {}) 286 resp = token_view(req) 287 resp2 = CsrfViewMiddleware().process_response(req, resp) 288 csrf_cookie = resp2.cookies[settings.CSRF_COOKIE_NAME] 289 self._check_token_present(resp, csrf_id=csrf_cookie.value) 290 291 def test_response_middleware_without_view_middleware(self): 292 """ 293 Check that CsrfResponseMiddleware finishes without error if the view middleware 294 has not been called, as is the case if a request middleware returns a response. 295 """ 296 req = self._get_GET_no_csrf_cookie_request() 297 resp = post_form_view(req) 298 CsrfMiddleware().process_response(req, resp) 299 300 def test_https_bad_referer(self): 301 """ 302 Test that a POST HTTP request with a bad referer is rejected 303 """ 304 req = self._get_POST_request_with_token() 305 req._is_secure = True 306 req.META['HTTP_HOST'] = 'www.example.com' 307 req.META['HTTP_REFERER'] = 'https://www.evil.org/somepage' 308 req2 = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) 309 self.assertNotEqual(None, req2) 310 self.assertEquals(403, req2.status_code) 311 312 def test_https_good_referer(self): 313 """ 314 Test that a POST HTTP request with a good referer is accepted 315 """ 316 req = self._get_POST_request_with_token() 317 req._is_secure = True 318 req.META['HTTP_HOST'] = 'www.example.com' 319 req.META['HTTP_REFERER'] = 'https://www.example.com/somepage' 320 req2 = CsrfViewMiddleware().process_view(req, post_form_view, (), {}) 321 self.assertEquals(None, req2) -
new file django/contrib/csrf/views.py
diff -r 1b4df7524b7c django/contrib/csrf/views.py
- + 1 from django.http import HttpResponseForbidden 2 from django.template import Context, Template 3 from django.conf import settings 4 5 # We include the template here, since one possible error in setting up CSRF is 6 # that the developer hasn't included the CSRF app in INSTALLED_APPS, in which 7 # case we won't be able to find the template. 8 CSRF_FAILRE_TEMPLATE = """ 9 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 10 <html lang="en"> 11 <head> 12 <meta http-equiv="content-type" content="text/html; charset=utf-8"> 13 <title>403 Forbidden</title> 14 </head> 15 <body> 16 <h1>403 Forbidden</h1> 17 <p>CSRF verification failed. Request aborted.</p> 18 {% if DEBUG %} 19 <h2>Help</h2> 20 21 <p>This can occur when there is a genuine Cross Site Request Forgery, or when 22 <a 23 href='http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ref-contrib-csrf'>Django's 24 CSRF mechanism</a> has not been used correctly. For POST forms, you need to 25 ensure:</p> 26 27 <ul> 28 <li>The view function uses <a 29 href='http://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext'><tt>RequestContext</tt></a> 30 for the template, instead of <tt>Context</tt>.</li> 31 32 <li>In the template, there is a <tt>{% templatetag openblock %} load csrf 33 {% templatetag closeblock %}</tt> command to load the the CSRF template 34 tag.</li> 35 36 <li>In the template, there is a <tt>{% templatetag openblock %} csrf_token 37 {% templatetag closeblock %}</tt> template tag inside each POST form that 38 targets an internal URL.</li> 39 40 <li>You have <tt>'django.contrib.csrf'</tt> in your INSTALLED_APPS setting.</li> 41 42 <li>You have <tt>'django.contrib.csrf.context_processors.csrf'</tt> in your TEMPLATE_CONTEXT_PROCESSORS setting.</li> 43 </ul> 44 45 <p>You're seeing the help section of this page because you have <code>DEBUG = 46 True</code> in your Django settings file. Change that to <code>False</code>, 47 and only the initial error message will be displayed. </p> 48 49 {% endif %} 50 </body> 51 </html> 52 """ 53 54 def csrf_failure(request): 55 """ 56 Default view used when request fails CSRF protection 57 """ 58 t = Template(CSRF_FAILRE_TEMPLATE) 59 c = Context({'DEBUG': settings.DEBUG}) 60 return HttpResponseForbidden(t.render(c), mimetype='text/html') -
django/contrib/formtools/templates/formtools/form.html
diff -r 1b4df7524b7c django/contrib/formtools/templates/formtools/form.html
a b 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/formtools/templates/formtools/preview.html
diff -r 1b4df7524b7c django/contrib/formtools/templates/formtools/preview.html
a b 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> -
docs/intro/tutorial01.txt
diff -r 1b4df7524b7c docs/intro/tutorial01.txt
a b 209 209 210 210 * :mod:`django.contrib.contenttypes` -- A framework for content types. 211 211 212 * :mod:`django.contrib.csrf` -- A security system for dealing with Cross 213 Site Request Forgeries 214 215 * :mod:`django.contrib.csrf` -- An easy-to-use system for protecting 216 against Cross Site Request Forgeries. 217 212 218 * :mod:`django.contrib.sessions` -- A session framework. 213 219 214 220 * :mod:`django.contrib.sites` -- A framework for managing multiple sites … … 216 222 217 223 These applications are included by default as a convenience for the common case. 218 224 219 Eachof these applications makes use of at least one database table, though,225 Most of these applications makes use of at least one database table, though, 220 226 so we need to create the tables in the database before we can use them. To do 221 227 that, run the following command: 222 228 … … 386 392 INSTALLED_APPS = ( 387 393 'django.contrib.auth', 388 394 'django.contrib.contenttypes', 395 'django.contrib.csrf', 389 396 'django.contrib.sessions', 390 397 'django.contrib.sites', 391 398 'mysite.polls' -
docs/intro/tutorial04.txt
diff -r 1b4df7524b7c docs/intro/tutorial04.txt
a b 16 16 17 17 .. code-block:: html+django 18 18 19 {% load csrf %} 19 20 <h1>{{ poll.question }}</h1> 20 21 21 22 {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %} 22 23 23 24 <form action="/polls/{{ poll.id }}/vote/" method="post"> 25 {% csrf_token %} 24 26 {% for choice in poll.choice_set.all %} 25 27 <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" /> 26 28 <label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br /> … … 46 48 * ``forloop.counter`` indicates how many times the :ttag:`for` tag has gone 47 49 through its loop 48 50 51 * Since we are creating a POST form (which can have the effect of modifying 52 data), we unfortunately need to worry about Cross Site Request Forgeries. 53 Thankfully, you don't have to worry too hard, because Django comes with 54 very easy-to-use system for protecting against it. In short, all POST 55 forms that are targetted at internal URLs need the ``{% csrf_token %}`` 56 template tag adding, and this tag in turn requires the ``{% load csrf %}`` 57 line. A 'middleware' which is installed by default checks for the 58 presence of the token in the submitted form data. 59 60 The ``{% csrf_token %}`` tag requires information from the request object, which 61 is not normally accessible from within the template context. To fix this, a 62 small adjustment needs to be made to the ``detail`` view, so that it looks like 63 the following:: 64 65 from django.template import RequestContext 66 # ... 67 def detail(request, poll_id): 68 p = get_object_or_404(Poll, pk=poll_id) 69 return render_to_response('polls/detail.html', {'poll': p}, 70 context_instance=RequestContext(request)) 71 72 The details of how this works are explained in the documentation for 73 :ref:`RequestContext <subclassing-context-requestcontext>`. 74 49 75 Now, let's create a Django view that handles the submitted data and does 50 76 something with it. Remember, in :ref:`Tutorial 3 <intro-tutorial03>`, we 51 77 created a URLconf for the polls application that includes this line:: … … 57 83 from django.shortcuts import get_object_or_404, render_to_response 58 84 from django.http import HttpResponseRedirect 59 85 from django.core.urlresolvers import reverse 86 from django.template import RequestContext 60 87 from mysite.polls.models import Choice, Poll 61 88 # ... 62 89 def vote(request, poll_id): … … 68 95 return render_to_response('polls/detail.html', { 69 96 'poll': p, 70 97 'error_message': "You didn't select a choice.", 71 } )98 }, context_instance=RequestContext(request)) 72 99 else: 73 100 selected_choice.votes += 1 74 101 selected_choice.save() -
docs/ref/contrib/csrf.txt
diff -r 1b4df7524b7c docs/ref/contrib/csrf.txt
a b 7 7 .. module:: django.contrib.csrf 8 8 :synopsis: Protects against Cross Site Request Forgeries 9 9 10 The C srfMiddleware classprovides easy-to-use protection against10 The CSRF middleware and template tag provides easy-to-use protection against 11 11 `Cross Site Request Forgeries`_. This type of attack occurs when a malicious 12 12 Web site creates a link or form button that is intended to perform some action 13 on your Web site, using the credentials of a logged-in user who is tricked 14 into clicking on the link in their browser. 13 on your Web site, using the credentials of a logged-in user who is tricked into 14 clicking on the link in their browser. A related type of attack, 'login CSRF', 15 where an attacking site tricks a user's browser into logging into a site with 16 someone else's credentials, is also covered. 15 17 16 The first defense against CSRF attacks is to ensure that GET requests 17 are side-effect free. POST requests can then be protected by adding this 18 middleware into your list of installed middleware. 18 The first defense against CSRF attacks is to ensure that GET requests are 19 side-effect free. POST requests can then be protected by following the steps 20 below. 21 22 .. versionadded:: 1.2 23 The 'contrib' apps, including the admin, depend on the functionality 24 described here. Anyone upgrading from earlier versions should read 25 the `Upgrading notes`_ carefully. 19 26 20 27 .. _Cross Site Request Forgeries: http://www.squarefree.com/securitytips/web-developers.html#CSRF 21 28 22 29 How to use it 23 30 ============= 24 31 25 Add the middleware ``'django.contrib.csrf.middleware.CsrfMiddleware'`` to 26 your list of middleware classes, :setting:`MIDDLEWARE_CLASSES`. It needs to process 27 the response after the SessionMiddleware, so must come before it in the 28 list. It also must process the response before things like compression 29 happen to the response, so it must come after GZipMiddleware in the 30 list. 32 .. versionchanged:: 1.2 33 The template tag functionality (the recommended way to use this) was added 34 in version 1.2. The previous method (still available) is described under 35 `Legacy method`_. 31 36 32 The ``CsrfMiddleware`` class is actually composed of two middleware: 33 ``CsrfViewMiddleware`` which performs the checks on incoming requests, 34 and ``CsrfResponseMiddleware`` which performs post-processing of the 35 result. This allows the individual components to be used and/or 36 replaced instead of using ``CsrfMiddleware``. 37 To enable CSRF protection for your views, follow these steps: 37 38 38 .. versionchanged:: 1.1 39 (previous versions of Django did not provide these two components 40 of ``CsrfMiddleware`` as described above) 39 1. Add the middleware 40 ``'django.contrib.csrf.middleware.CsrfViewMiddleware'`` to your list of 41 middleware classes, :setting:`MIDDLEWARE_CLASSES`. (It should come 42 before ``CsrfResponseMiddleware`` if that is being used, and before any 43 view middleware that assume that CSRF attacks have been dealt with.) 44 45 2. Add ``'django.contrib.csrf'`` to your :setting:`INSTALLED_APPS`. 46 47 3. In any template that uses a POST form, first load the 'csrf' template tag 48 library:: 49 50 {% load csrf %} 51 52 Then use the ``csrf_token`` tag inside the ``<form>`` element, e.g.:: 53 54 <form action="" method="POST">{% csrf_token %} 55 56 This should not be done for POST forms that target external URLs, since 57 that would cause the CSRF token to be leaked, leading to a vulnerability. 58 59 4. In the corresponding view functions, ensure that the 60 ``'django.contrib.csrf.context_processors.csrf'`` context processor is 61 being used. Usually, this can be done in one of two ways: 62 63 1. Using RequestContext: 64 65 1. Ensure ``'django.contrib.csrf.context_processors.csrf'`` is present 66 in your :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting. It is 67 present by default. 68 69 2. Use ``RequestContext`` as the context instance in the relevant 70 views. If you are using generic views or contrib apps, you are 71 covered already. 72 73 2. Manually import and use the processor to generate the CSRF token and 74 add it to the template context. e.g.:: 75 76 from django.contrib.csrf.context_processors import csrf 77 from django.template import Context 78 from django.shortcuts import render_to_response 79 def my_view(request): 80 c = Context() 81 c.update(csrf(request)) 82 return render_to_response("a_template.html", context_instance=c) 83 84 Legacy method 85 ------------- 86 87 In Django 1.1, the template tag did not exist. Instead, a post-processing 88 middleware that re-wrote POST forms to include the CRSF token was used. If you 89 are upgrading a site from version 1.1 or earlier, please read this section and 90 the `Upgrading notes`_ below. The post-processing middleware is still available 91 as ``CsrfResponseMiddleware``, and it can be used by following these steps: 92 93 1. Follow step 1 above to install ``CsrfViewMiddleware``. 94 95 2. Add ``'django.contrib.csrf.middleware.CsrfResponseMiddleware'`` to your 96 :setting:`MIDDLEWARE_CLASSES` setting. 97 98 ``CsrfResponseMiddleware`` needs to process the response before things 99 like compression happen to the response, so it must come after 100 ``GZipMiddleware`` in the list. It also must come after 101 ``CsrfViewMiddleware``. 102 103 Use of the ``CsrfResponseMiddleware`` is not recommended because of the 104 performance hit it imposes, and because of a potential security problem (see 105 below). It can be used as an interim measure until applications have been 106 updated to use the ``{% crsf_token %}`` tag. It is deprecated and will be 107 removed in Django 1.4. 108 109 Django 1.1 and earlier provided a single ``CsrfMiddleware`` class. This is also 110 still available for backwards compatibility. It combines the functions of the 111 two middleware. 112 113 Note also that previous versions of these classes depended on the sessions 114 framework, but this dependency has now been removed, with backward compatibility 115 support so that upgrading will not produce any issues. 116 117 Security of legacy method 118 ~~~~~~~~~~~~~~~~~~~~~~~~~ 119 120 The post-processing ``CsrfResponseMiddleware`` adds the CSRF token to all POST 121 forms (unless the view has been decorated with ``csrf_response_exempt``). If 122 the POST form has an external untrusted site as its target, rather than an 123 internal page, that site will be sent the CSRF token when the form is submitted. 124 Armed with this leaked information, that site will then be able to successfully 125 launch a CSRF attack on your site against that user. The 126 ``@csrf_response_exempt`` decorator can be used to fix this, but only if the 127 page doesn't also contain internal forms that require the token. 128 129 Upgrading notes 130 --------------- 131 132 When upgrading to version 1.2 or later, you may have applications that rely on 133 the old post-processing functionality for CSRF protection, or you may not have 134 enabled any CSRF protection. This section outlines the steps necessary for a 135 smooth upgrade, without having to fix all the applications to use the new 136 template tag method immediately. 137 138 If you are using any of the contrib apps (such as the admin), there are some 139 required steps for these applications to continue working. First, the CSRF 140 application must be added to :setting:`INSTALLED_APPS` (See `How to use it`_ 141 above, step 2). Second, the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting must 142 be updated (step 4.1.1 above). 143 144 If you have ``CsrfMiddleware`` in your :setting:`MIDDLEWARE_CLASSES`, you will now 145 have a working installation with CSRF protection. It is recommended at this 146 point that you replace ``CsrfMiddleware`` with its two components, 147 ``CsrfViewMiddleware`` and ``CsrfResponseMiddleware`` (in that order). 148 149 If you do not have any of the middleware in your :setting:`MIDDLEWARE_CLASSES`, 150 you will have a working installation but without any CSRF protection (just as 151 you had before). It is strongly recommended to install ``CsrfViewMiddleware`` 152 and ``CsrfResponseMiddleware``, but if you are not interested in having any CSRF 153 protection, you can simply stop here. 154 155 Assuming you have followed the above, all views in your Django site will now be 156 protected by the ``CsrfViewMiddleware``. Contrib apps meet the requirements 157 imposed by the ``CsrfViewMiddleware`` using the template tag, and other 158 applications in your project will meet its requirements by virtue of the 159 ``CsrfResponseMiddleware``. 160 161 The next step is to update all your applications to use the template tag, as 162 described in `How to use it`_, steps 3-4. This can be done as soon as is 163 practical. Any applications that are updated will now require Django 1.2 or 164 later, since they will use the CSRF template tag library which was not available 165 in earlier versions. 166 167 Finally, once all applications are upgraded, ``CsrfResponseMiddleware`` can be 168 removed from your settings. 169 170 While ``CsrfResponseMiddleware`` is still in use, the ``csrf_response_exempt`` 171 decorator, described in `Exceptions`_, may be useful. The post-processing 172 middleware imposes a performance hit and a potential vulnerability, and any 173 views that have been upgraded to use the new template tag method no longer need 174 it. 41 175 42 176 Exceptions 43 177 ---------- 44 178 45 179 .. versionadded:: 1.1 46 180 47 To manually exclude a view function from being handled by the48 CsrfMiddleware, you can use the ``csrf_exempt`` decorator, found in 49 the``django.contrib.csrf.middleware`` module. For example::181 To manually exclude a view function from being handled by either of the two CSRF 182 middleware, you can use the ``csrf_exempt`` decorator, found in the 183 ``django.contrib.csrf.middleware`` module. For example:: 50 184 51 185 from django.contrib.csrf.middleware import csrf_exempt 52 186 … … 54 188 return HttpResponse('Hello world') 55 189 my_view = csrf_exempt(my_view) 56 190 57 Like the middleware itself, the ``csrf_exempt`` decorator is composed58 of two parts: a ``csrf_view_exempt`` decorator and a 59 ``csrf_response_exempt`` decorator, found in the same module. These 60 disable the view protection mechanism (``CsrfViewMiddleware``) and the 61 response post-processing (``CsrfResponseMiddleware``) respectively. 62 They can be used individually ifrequired.191 Like the middleware, the ``csrf_exempt`` decorator is composed of two parts: a 192 ``csrf_view_exempt`` decorator and a ``csrf_response_exempt`` decorator, found 193 in the same module. These disable the view protection mechanism 194 (``CsrfViewMiddleware``) and the response post-processing 195 (``CsrfResponseMiddleware``) respectively. They can be used individually if 196 required. 63 197 64 You don't have to worry about doing this for most AJAX views. Any 65 request sent with "X-Requested-With: XMLHttpRequest" is automatically 66 exempt. (See the next section.) 198 You don't have to worry about doing this for most AJAX views. Any request sent 199 with "X-Requested-With: XMLHttpRequest" is automatically exempt. (See the next 200 section.) 201 202 Subdomains 203 ---------- 204 205 By default, CSRF cookies are specific to the subdomain they are set for. This 206 means that a form served from one subdomain (e.g. server1.example.com) will not 207 be able to have a target on another subdomain (e.g. server2.example.com). This 208 restriction can be removed by setting :setting:`CSRF_COOKIE_DOMAIN` to be 209 something like ``".example.com"``. 210 211 Please note that, with or without use of this setting, this CSRF protection 212 mechanism is not safe against cross-subdomain attacks -- see `Limitations`_. 213 214 Rejected requests 215 ================= 216 217 By default, a '403 Forbidden' response is sent to the user if an incoming 218 request fails the checks performed by ``CsrfViewMiddleware``. This should 219 usually only be seen when there is a genuine Cross Site Request Forgery, or 220 when, due to a programming error, the CSRF token has not been included with a 221 POST form. 222 223 No logging is done, and the error message is not very friendly, so you may want 224 to provide your own page for handling this condition. To do this, simply set 225 the :setting:`CSRF_FAILURE_VIEW` setting to a dotted path to your own view 226 function. 67 227 68 228 How it works 69 229 ============ 70 230 71 CsrfMiddleware does twothings:231 The CSRF protection is based on the following things: 72 232 73 1. It modifies outgoing requests by adding a hidden form field to all 74 'POST' forms, with the name 'csrfmiddlewaretoken' and a value which is 75 a hash of the session ID plus a secret. If there is no session ID set, 76 this modification of the response isn't done, so there is very little 77 performance penalty for those requests that don't have a session. 78 (This is done by ``CsrfResponseMiddleware``). 233 1. A CSRF cookie that is set to a random value (a session independent nonce, as 234 it is called), which other sites will not have access to. 79 235 80 2. On all incoming POST requests that have the session cookie set, it 81 checks that the 'csrfmiddlewaretoken' is present and correct. If it82 isn't, the user will get a 403 error. (This is done by83 ``CsrfViewMiddleware``)236 This cookie is set by ``CsrfViewMiddleware``. It is meant to be permanent, 237 but since there is no way to set a cookie that never expires, it is sent with 238 every response that has called ``django.contrib.csrf.middleware.get_token()`` 239 (the function used internally to retrieve the CSRF token). 84 240 85 This ensures that only forms that have originated from your Web site 86 can be used to POST data back. 241 2. A hidden form field with the name 'csrfmiddlewaretoken' present in all 242 outgoing POST forms. The value of this field is the value of the CSRF 243 cookie. 244 245 This part is done by the template tag (and with the legacy method, it is done 246 by ``CsrfResponseMiddleware``). 247 248 3. For all incoming POST requests, a CSRF cookie must be present, and the 249 'csrfmiddlewaretoken' field must be present and correct. If it isn't, the 250 user will get a 403 error. 251 252 This check is done by ``CsrfViewMiddleware``. 253 254 4. In addition, for HTTPS requests, strict referer checking is done by 255 ``CsrfViewMiddleware``. This is necessary to address a Man-In-The-Middle 256 attack that is possible under HTTPS when using a session independent nonce, 257 due to the fact that HTTP 'Set-Cookie' headers are (unfortunately) accepted 258 by clients that are talking to a site under HTTPS. (Referer checking is not 259 done for HTTP requests, because under HTTP, the presence of the Referer 260 header is not reliable enough.) 261 262 This ensures that only forms that have originated from your Web site can be used 263 to POST data back. 87 264 88 265 It deliberately only targets HTTP POST requests (and the corresponding POST 89 forms). GET requests ought never to have any potentially dangerous side 90 effects (see `9.1.1 Safe Methods, HTTP 1.1, RFC 2616`_), and so a 91 CSRF attack with a GET request ought to be harmless. 92 93 POST requests that are not accompanied by a session cookie are not protected, 94 but they do not need to be protected, since the 'attacking' Web site 95 could make these kind of requests anyway. 96 97 The Content-Type is checked before modifying the response, and only 98 pages that are served as 'text/html' or 'application/xml+xhtml' 99 are modified. 266 forms). GET requests ought never to have any potentially dangerous side effects 267 (see `9.1.1 Safe Methods, HTTP 1.1, RFC 2616`_), and so a CSRF attack with a GET 268 request ought to be harmless. 100 269 101 270 The middleware tries to be smart about requests that come in via AJAX. Many 102 271 JavaScript toolkits send an "X-Requested-With: XMLHttpRequest" HTTP header; 103 272 these requests are detected and automatically *not* handled by this middleware. 104 273 We can do this safely because, in the context of a browser, the header can only 105 274 be added by using ``XMLHttpRequest``, and browsers already implement a 106 same-domain policy for ``XMLHttpRequest``. (Note that this is not secure if you 107 don't trust content within the same domain or subdomains.) 275 same-domain policy for ``XMLHttpRequest``. 108 276 277 ``CsrfResponseMiddleware`` checks the Content-Type before modifying the 278 response, and only pages that are served as 'text/html' or 279 'application/xml+xhtml' are modified. 109 280 110 281 .. _9.1.1 Safe Methods, HTTP 1.1, RFC 2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html 111 282 112 283 Limitations 113 284 =========== 114 285 115 CsrfMiddleware requires Django's session framework to work. If you have 116 a custom authentication system that manually sets cookies and the like, 117 it won't help you. 286 Subdomains within a site will be able to set cookies on the client for the whole 287 domain. By setting the cookie and using a corresponding token, subdomains will 288 be able to circumvent the CSRF protection. The only way to avoid this is to 289 ensure that subdomains are controlled by trusted users (or, are at least unable 290 to set cookies). Note that even without CSRF, there are other vulnerabilities, 291 such as session fixation, that make giving subdomains to untrusted parties a bad 292 idea, and these vulnerabilities cannot easily be fixed with current browsers. 118 293 119 If you r app creates HTML pages and forms in some unusual way, (e.g.120 it sends fragments of HTML in JavaScript document.write statements) 121 you might bypass the filter that adds the hidden field to the form, 122 in which case form submission will always fail. It may still be possible 123 to use the middleware, provided you can find some way to get the 124 CSRF token and ensure that is included when your form is submitted.294 If you are using ``CsrfResponseMiddleware`` and your app creates HTML pages and 295 forms in some unusual way, (e.g. it sends fragments of HTML in JavaScript 296 document.write statements) you might bypass the filter that adds the hidden 297 field to the form, in which case form submission will always fail. You should 298 use the template tag or :meth:`django.contrib.csrf.middleware.get_token` to get 299 the CSRF token and ensure that is included when your form is submitted. -
docs/ref/contrib/formtools/form-wizard.txt
diff -r 1b4df7524b7c docs/ref/contrib/formtools/form-wizard.txt
a b 174 174 .. code-block:: html+django 175 175 176 176 {% extends "base.html" %} 177 {% load csrf %} 177 178 178 179 {% block content %} 179 180 <p>Step {{ step }} of {{ step_count }}</p> 180 <form action="." method="post"> 181 <form action="." method="post">{% csrf_token %} 181 182 <table> 182 183 {{ form }} 183 184 </table> -
docs/ref/settings.txt
diff -r 1b4df7524b7c docs/ref/settings.txt
a b 144 144 The default number of seconds to cache a page when the caching middleware or 145 145 ``cache_page()`` decorator is used. 146 146 147 .. setting:: CSRF_COOKIE_NAME 148 149 CSRF_COOKIE_NAME 150 ---------------- 151 Default: ``'csrftoken'`` 152 153 The name of the cookie to use for the CSRF authentication token. This can be whatever you 154 want. See :ref:`ref-contrib-csrf`. 155 156 .. setting:: CSRF_COOKIE_DOMAIN 157 158 CSRF_COOKIE_DOMAIN 159 ------------------ 160 161 Default: ``None`` 162 163 The domain to be used when setting the CSRF cookie. This can be useful for 164 allowing cross-subdomain requests to be exluded from the normal cross site 165 request forgery protection. It should be set to a string such as 166 ``".lawrence.com"`` to allow a POST request from a form on one subdomain to be 167 accepted by accepted by a view served from another subdomain. 168 169 .. setting:: CSRF_FAILURE_VIEW 170 171 CSRF_FAILURE_VIEW 172 ----------------- 173 174 Default: ``'django.contrib.csrf.views.csrf_failure'`` 175 176 A dotted path to the view function to be used when an incoming request 177 is rejected by the CSRF protection. See :ref:`ref-contrib-csrf`. 178 147 179 .. setting:: DATABASE_ENGINE 148 180 149 181 DATABASE_ENGINE … … 751 783 752 784 ('django.middleware.common.CommonMiddleware', 753 785 'django.contrib.sessions.middleware.SessionMiddleware', 786 'django.contrib.csrf.middleware.CsrfViewMiddleware', 754 787 'django.contrib.auth.middleware.AuthenticationMiddleware',) 755 788 756 789 A tuple of middleware classes to use. See :ref:`topics-http-middleware`. -
docs/ref/templates/api.txt
diff -r 1b4df7524b7c docs/ref/templates/api.txt
a b 311 311 ("django.core.context_processors.auth", 312 312 "django.core.context_processors.debug", 313 313 "django.core.context_processors.i18n", 314 "django.core.context_processors.media") 314 "django.core.context_processors.media", 315 "django.contrib.csrf.context_processors.csrf") 315 316 316 317 Each processor is applied in order. That means, if one processor adds a 317 318 variable to the context and a second processor adds a variable with the same … … 404 405 ``RequestContext`` will contain a variable ``MEDIA_URL``, providing the 405 406 value of the :setting:`MEDIA_URL` setting. 406 407 408 django.contrib.csrf.context_processors.csrf 409 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 410 411 .. versionadded:: 1.2 412 413 This processor adds a token that is needed by the ``csrf_token`` template tag 414 for protection against :ref:`Cross Site Request Forgeries <ref-contrib-csrf>`. 415 407 416 django.core.context_processors.request 408 417 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 409 418 -
docs/topics/auth.txt
diff -r 1b4df7524b7c docs/topics/auth.txt
a b 754 754 .. code-block:: html 755 755 756 756 {% extends "base.html" %} 757 {% load csrf %} 757 758 758 759 {% block content %} 759 760 … … 761 762 <p>Your username and password didn't match. Please try again.</p> 762 763 {% endif %} 763 764 764 <form method="post" action="{% url django.contrib.auth.views.login %}"> 765 <form method="post" action="{% url django.contrib.auth.views.login %}">{% csrf_token %} 765 766 <table> 766 767 <tr> 767 768 <td>{{ form.username.label_tag }}</td> -
docs/topics/http/middleware.txt
diff -r 1b4df7524b7c docs/topics/http/middleware.txt
a b 29 29 MIDDLEWARE_CLASSES = ( 30 30 'django.middleware.common.CommonMiddleware', 31 31 'django.contrib.sessions.middleware.SessionMiddleware', 32 'django.contrib.csrf.middleware.CsrfViewMiddleware', 32 33 'django.contrib.auth.middleware.AuthenticationMiddleware', 33 34 ) 34 35 -
tests/regressiontests/admin_views/tests.py
diff -r 1b4df7524b7c tests/regressiontests/admin_views/tests.py
a b 874 874 # 4 action inputs (3 regular checkboxes, 1 checkbox to select all) 875 875 # main form submit button = 1 876 876 # search field and search submit button = 2 877 # 6 + 2 + 1 + 2 = 11inputs877 # 6 + 2 + 4 + 1 + 2 + 1 = 15 inputs 878 878 self.failUnlessEqual(response.content.count("<input"), 15) 879 879 # 1 select per object = 3 selects 880 880 self.failUnlessEqual(response.content.count("<select"), 4) -
tests/runtests.py
diff -r 1b4df7524b7c tests/runtests.py
a b 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():