From 0af14b2eaa0bf0821a8aacc8486489a1eb348397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vio=20Juvenal?= Date: Wed, 24 May 2017 16:36:45 -0700 Subject: [PATCH] Refs #16870 -- Doc'd that CSRF protection requires the Referer header. --- django/views/csrf.py | 8 ++++++++ docs/ref/csrf.txt | 12 ++++++++++++ tests/view_tests/tests/test_csrf.py | 7 +++++++ 3 files changed, 27 insertions(+) diff --git a/django/views/csrf.py b/django/views/csrf.py index 6119f3b49d..0689df84e4 100644 --- a/django/views/csrf.py +++ b/django/views/csrf.py @@ -41,6 +41,7 @@ CSRF_FAILURE_TEMPLATE = """ {% if no_referer %}

{{ no_referer1 }}

{{ no_referer2 }}

+

{{ no_referer3 }}

{% endif %} {% if no_cookie %}

{{ no_cookie1 }}

@@ -119,6 +120,13 @@ def csrf_failure(request, reason="", template_name=CSRF_FAILURE_TEMPLATE_NAME): "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_referer3': _( + "If you are using the tag or including the 'Referrer-Policy: " + "no-referrer' header, please remove them. The CSRF protection " + "requires the 'Referer' header to do strict referer checking. If " + "you're concerned about privacy, use alternatives like " + " for links to third-party sites."), 'no_cookie': reason == REASON_NO_CSRF_COOKIE, 'no_cookie1': _( "You are seeing this message because this site requires a CSRF " diff --git a/docs/ref/csrf.txt b/docs/ref/csrf.txt index 802d7251ab..dd5ea479ae 100644 --- a/docs/ref/csrf.txt +++ b/docs/ref/csrf.txt @@ -315,7 +315,19 @@ the HOST header ` and that there aren't any (because XSS vulnerabilities already let an attacker do anything a CSRF vulnerability allows and much worse). +.. admonition:: Removing the ``Referer`` header + + To avoid disclosing the referrer URL to third-party sites, you might want + to `disable the referer`_ on your site's ```` tags. For example, you + might use the ```` tag or + include the ``Referrer-Policy: no-referrer`` header. Due to the CSRF + protection's strict referer checking on HTTPS requests, those techniques + cause a CSRF failure on requests with 'unsafe' methods. Instead, use + alternatives like ``"`` for links to third-party + sites. + .. _BREACH: http://breachattack.com/ +.. _disable the referer: https://www.w3.org/TR/referrer-policy/#referrer-policy-delivery Caching ======= diff --git a/tests/view_tests/tests/test_csrf.py b/tests/view_tests/tests/test_csrf.py index 8a3f86c376..4c20cb897d 100644 --- a/tests/view_tests/tests/test_csrf.py +++ b/tests/view_tests/tests/test_csrf.py @@ -55,6 +55,13 @@ class CsrfViewTests(SimpleTestCase): 'HTTPS connections, or for 'same-origin' requests.', status_code=403, ) + self.assertContains( + response, + 'If you are using the <meta name="referrer" ' + 'content="no-referrer"> tag or including the ' + ''Referrer-Policy: no-referrer' header, please remove them.', + status_code=403, + ) def test_no_cookies(self): """