Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #21322 -- Error message when CSRF cookie is missing

Thanks to Henrik Levkowetz and olau for their reports and initial patches.
  • Loading branch information...
commit 9b95fa7777c4b484f8053b87f48d65c853945f19 1 parent f67e18f
@Bouke Bouke authored claudep committed
Showing with 50 additions and 4 deletions.
  1. +15 −1 django/views/csrf.py
  2. +35 −3 tests/view_tests/tests/test_csrf.py
View
16 django/views/csrf.py
@@ -41,6 +41,10 @@
<p>{{ no_referer1 }}</p>
<p>{{ no_referer2 }}</p>
{% endif %}
+{% if no_cookie %}
+ <p>{{ no_cookie1 }}</p>
+ <p>{{ no_cookie2 }}</p>
+{% endif %}
</div>
{% if DEBUG %}
<div id="info">
@@ -95,7 +99,7 @@ def csrf_failure(request, reason=""):
"""
Default view used when request fails CSRF protection
"""
- from django.middleware.csrf import REASON_NO_REFERER
+ from django.middleware.csrf import REASON_NO_REFERER, REASON_NO_CSRF_COOKIE
t = Template(CSRF_FAILURE_TEMPLATE)
c = Context({
'title': _("Forbidden"),
@@ -111,6 +115,16 @@ def csrf_failure(request, reason=""):
"If you have configured your browser to disable 'Referer' headers, "
"please re-enable them, at least for this site, or for HTTPS "
"connections, or for 'same-origin' requests."),
+ 'no_cookie': reason == REASON_NO_CSRF_COOKIE,
+ 'no_cookie1': _(
+ "You are seeing this message because this site requires a CSRF "
+ "cookie when submitting forms. This cookie is required for "
+ "security reasons, to ensure that your browser is not being "
+ "hijacked by third parties."),
+ 'no_cookie2': _(
+ "If you have configured your browser to disable cookies, please "
+ "re-enable them, at least for this site, or for 'same-origin' "
+ "requests."),
'DEBUG': settings.DEBUG,
'more': _("More information is available with DEBUG=True."),
})
View
38 tests/view_tests/tests/test_csrf.py
@@ -5,6 +5,10 @@
class CsrfViewTests(TestCase):
urls = "view_tests.urls"
+ def setUp(self):
+ super(CsrfViewTests, self).setUp()
+ self.client = Client(enforce_csrf_checks=True)
+
@override_settings(
USE_I18N=True,
MIDDLEWARE_CLASSES=(
@@ -17,17 +21,45 @@ def test_translation(self):
"""
Test that an invalid request is rejected with a localized error message.
"""
- self.client = Client(enforce_csrf_checks=True)
- response = self.client.post('/', HTTP_HOST='www.example.com')
+ response = self.client.post('/')
self.assertContains(response, "Forbidden", status_code=403)
self.assertContains(response,
"CSRF verification failed. Request aborted.",
status_code=403)
with self.settings(LANGUAGE_CODE='nl'), override('en-us'):
- response = self.client.post('/', HTTP_HOST='www.example.com')
+ response = self.client.post('/')
self.assertContains(response, "Verboden", status_code=403)
self.assertContains(response,
"CSRF-verificatie mislukt. Verzoek afgebroken.",
status_code=403)
+
+ @override_settings(
+ SECURE_PROXY_SSL_HEADER=('HTTP_X_FORWARDED_PROTO', 'https')
+ )
+ def test_no_referer(self):
+ """
+ Referer header is strictly checked for POST over HTTPS. Trigger the
+ exception by sending an incorrect referer.
+ """
+ response = self.client.post('/', HTTP_X_FORWARDED_PROTO='https')
+ self.assertContains(response,
+ "You are seeing this message because this HTTPS "
+ "site requires a &#39;Referer header&#39; to be "
+ "sent by your Web browser, but none was sent.",
+ status_code=403)
+
+ def test_no_cookies(self):
+ """
+ The CSRF cookie is checked for POST. Failure to send this cookie should
+ provide a nice error message.
+ """
+ response = self.client.post('/')
+ self.assertContains(response,
+ "You are seeing this message because this site "
+ "requires a CSRF cookie when submitting forms. "
+ "This cookie is required for security reasons, to "
+ "ensure that your browser is not being hijacked "
+ "by third parties.",
+ status_code=403)

0 comments on commit 9b95fa7

Please sign in to comment.
Something went wrong with that request. Please try again.