diff --git a/django/core/checks/security/csrf.py b/django/core/checks/security/csrf.py index 1cd0ace56d5..d9dd47b3eab 100644 --- a/django/core/checks/security/csrf.py +++ b/django/core/checks/security/csrf.py @@ -20,14 +20,6 @@ W016 = Warning( id='security.W016', ) -W017 = Warning( - "You have 'django.middleware.csrf.CsrfViewMiddleware' in your " - "MIDDLEWARE, but you have not set CSRF_COOKIE_HTTPONLY to True. " - "Using an HttpOnly CSRF cookie makes it more difficult for cross-site " - "scripting attacks to steal the CSRF token.", - id='security.W017', -) - def _csrf_middleware(): return ("django.middleware.csrf.CsrfViewMiddleware" in settings.MIDDLEWARE_CLASSES or @@ -48,13 +40,3 @@ def check_csrf_cookie_secure(app_configs, **kwargs): settings.CSRF_COOKIE_SECURE ) return [] if passed_check else [patch_middleware_message(W016)] - - -@register(Tags.security, deploy=True) -def check_csrf_cookie_httponly(app_configs, **kwargs): - passed_check = ( - settings.CSRF_USE_SESSIONS or - not _csrf_middleware() or - settings.CSRF_COOKIE_HTTPONLY - ) - return [] if passed_check else [patch_middleware_message(W017)] diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 3b16921e522..c6f7e518ef0 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -593,7 +593,9 @@ The following checks are run if you use the :option:`check --deploy` option: sniffers to steal the CSRF token. * **security.W017**: :setting:`CSRF_COOKIE_HTTPONLY` is not set to ``True``. Using an ``HttpOnly`` CSRF cookie makes it more difficult for cross-site - scripting attacks to steal the CSRF token. + scripting attacks to steal the CSRF token. *This check is removed in Django + 1.11 as the* :setting:`CSRF_COOKIE_HTTPONLY` *setting offers no pratical + benefit.* * **security.W018**: You should not have :setting:`DEBUG` set to ``True`` in deployment. * **security.W019**: You have diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index 87dbc895847..1d28c96137e 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -334,10 +334,18 @@ Default: ``False`` Whether to use ``HttpOnly`` flag on the CSRF cookie. If this is set to ``True``, client-side JavaScript will not to be able to access the CSRF cookie. -This can help prevent malicious JavaScript from bypassing CSRF protection. If -you enable this and need to send the value of the CSRF token with Ajax requests, -your JavaScript will need to pull the value from a hidden CSRF token form input -on the page instead of from the cookie. +Designating the CSRF cookie as ``HttpOnly`` doesn't offer any practical +protection because CSRF is only to protect against cross-domain attacks. If an +attacker can read the cookie via JavaScript, they're already on the same domain +as far as the browser knows, so they can do anything they like anyway. (XSS is +a much bigger hole than CSRF.) + +Although the setting offers little practical benefit, it's sometimes required +by security auditors. + +If you enable this and need to send the value of the CSRF token with an AJAX +request, your JavaScript must pull the value from a hidden CSRF token form +input on the page instead of from the cookie. See :setting:`SESSION_COOKIE_HTTPONLY` for details on ``HttpOnly``. diff --git a/tests/check_framework/test_security.py b/tests/check_framework/test_security.py index 1e6d2fac8b8..8c3b73d8bb1 100644 --- a/tests/check_framework/test_security.py +++ b/tests/check_framework/test_security.py @@ -192,48 +192,6 @@ class CheckCSRFCookieSecureTest(SimpleTestCase): self.assertEqual(self.func(None), []) -class CheckCSRFCookieHttpOnlyTest(SimpleTestCase): - @property - def func(self): - from django.core.checks.security.csrf import check_csrf_cookie_httponly - return check_csrf_cookie_httponly - - @override_settings( - MIDDLEWARE=["django.middleware.csrf.CsrfViewMiddleware"], - CSRF_COOKIE_HTTPONLY=False) - def test_with_csrf_cookie_httponly_false(self): - """ - Warn if CsrfViewMiddleware is in MIDDLEWARE but - CSRF_COOKIE_HTTPONLY isn't True. - """ - self.assertEqual(self.func(None), [csrf.W017]) - - @override_settings( - MIDDLEWARE=["django.middleware.csrf.CsrfViewMiddleware"], - CSRF_USE_SESSIONS=True, - CSRF_COOKIE_HTTPONLY=False) - def test_use_sessions_with_csrf_cookie_httponly_false(self): - """ - No warning if CSRF_COOKIE_HTTPONLY isn't True while CSRF_USE_SESSIONS - is True. - """ - self.assertEqual(self.func(None), []) - - @override_settings(MIDDLEWARE=[], MIDDLEWARE_CLASSES=[], CSRF_COOKIE_HTTPONLY=False) - def test_with_csrf_cookie_httponly_false_no_middleware(self): - """ - No warning if CsrfViewMiddleware isn't in MIDDLEWARE, even if - CSRF_COOKIE_HTTPONLY is False. - """ - self.assertEqual(self.func(None), []) - - @override_settings( - MIDDLEWARE=["django.middleware.csrf.CsrfViewMiddleware"], - CSRF_COOKIE_HTTPONLY=True) - def test_with_csrf_cookie_httponly_true(self): - self.assertEqual(self.func(None), []) - - class CheckSecurityMiddlewareTest(SimpleTestCase): @property def func(self):