Commit 9b95fa77 authored by Bouke Haarsma's avatar Bouke Haarsma Committed by Claude Paroz
Browse files

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

Thanks to Henrik Levkowetz and olau for their reports and initial patches.
parent f67e18f3
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -41,6 +41,10 @@ CSRF_FAILURE_TEMPLATE = """
  <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."),
    })
+35 −3
Original line number Diff line number Diff line
@@ -5,6 +5,10 @@ from django.utils.translation import override
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 @@ class CsrfViewTests(TestCase):
        """
        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)