From 54da6e2ac20bde80e0de9e35aa0c40ae1dd13943 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 23 Apr 2021 08:59:35 -0400 Subject: [PATCH] Fixed #32678 -- Removed SECURE_BROWSER_XSS_FILTER setting. --- django/conf/global_settings.py | 1 - django/core/checks/security/base.py | 6 +++--- django/middleware/security.py | 4 ---- docs/ref/checks.txt | 5 ++--- docs/ref/middleware.txt | 28 ---------------------------- docs/ref/settings.txt | 15 --------------- docs/releases/4.0.txt | 18 ++++++++++++++++++ tests/middleware/test_security.py | 28 ---------------------------- 8 files changed, 23 insertions(+), 82 deletions(-) diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index 0827e85f691..18c8d9330d6 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -634,7 +634,6 @@ SILENCED_SYSTEM_CHECKS = [] ####################### # SECURITY MIDDLEWARE # ####################### -SECURE_BROWSER_XSS_FILTER = False SECURE_CONTENT_TYPE_NOSNIFF = True SECURE_CROSS_ORIGIN_OPENER_POLICY = 'same-origin' SECURE_HSTS_INCLUDE_SUBDOMAINS = False diff --git a/django/core/checks/security/base.py b/django/core/checks/security/base.py index d95fab19b96..dacbfcfda9b 100644 --- a/django/core/checks/security/base.py +++ b/django/core/checks/security/base.py @@ -19,9 +19,9 @@ SECRET_KEY_MIN_UNIQUE_CHARACTERS = 5 W001 = Warning( "You do not have 'django.middleware.security.SecurityMiddleware' " "in your MIDDLEWARE so the SECURE_HSTS_SECONDS, " - "SECURE_CONTENT_TYPE_NOSNIFF, SECURE_BROWSER_XSS_FILTER, " - "SECURE_REFERRER_POLICY, SECURE_CROSS_ORIGIN_OPENER_POLICY, " - "and SECURE_SSL_REDIRECT settings will have no effect.", + "SECURE_CONTENT_TYPE_NOSNIFF, SECURE_REFERRER_POLICY, " + "SECURE_CROSS_ORIGIN_OPENER_POLICY, and SECURE_SSL_REDIRECT settings will " + "have no effect.", id='security.W001', ) diff --git a/django/middleware/security.py b/django/middleware/security.py index b9c5da9db57..d2c2bf2d3ff 100644 --- a/django/middleware/security.py +++ b/django/middleware/security.py @@ -12,7 +12,6 @@ class SecurityMiddleware(MiddlewareMixin): self.sts_include_subdomains = settings.SECURE_HSTS_INCLUDE_SUBDOMAINS self.sts_preload = settings.SECURE_HSTS_PRELOAD self.content_type_nosniff = settings.SECURE_CONTENT_TYPE_NOSNIFF - self.xss_filter = settings.SECURE_BROWSER_XSS_FILTER self.redirect = settings.SECURE_SSL_REDIRECT self.redirect_host = settings.SECURE_SSL_HOST self.redirect_exempt = [re.compile(r) for r in settings.SECURE_REDIRECT_EXEMPT] @@ -42,9 +41,6 @@ class SecurityMiddleware(MiddlewareMixin): if self.content_type_nosniff: response.headers.setdefault('X-Content-Type-Options', 'nosniff') - if self.xss_filter: - response.headers.setdefault('X-XSS-Protection', '1; mode=block') - if self.referrer_policy: # Support a comma-separated string or iterable of values to allow # fallback. diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index a9f51b3ce95..f304da7e116 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -416,8 +416,7 @@ The following checks are run if you use the :option:`check --deploy` option: * **security.W001**: You do not have :class:`django.middleware.security.SecurityMiddleware` in your :setting:`MIDDLEWARE` so the :setting:`SECURE_HSTS_SECONDS`, - :setting:`SECURE_CONTENT_TYPE_NOSNIFF`, :setting:`SECURE_BROWSER_XSS_FILTER`, - :setting:`SECURE_REFERRER_POLICY`, + :setting:`SECURE_CONTENT_TYPE_NOSNIFF`, :setting:`SECURE_REFERRER_POLICY`, :setting:`SECURE_CROSS_ORIGIN_OPENER_POLICY`, and :setting:`SECURE_SSL_REDIRECT` settings will have no effect. * **security.W002**: You do not have @@ -446,7 +445,7 @@ The following checks are run if you use the :option:`check --deploy` option: set to ``True``, so your pages will not be served with an ``'X-Content-Type-Options: nosniff'`` header. You should consider enabling this header to prevent the browser from identifying content types incorrectly. -* **security.W007**: Your :setting:`SECURE_BROWSER_XSS_FILTER` setting is not +* **security.W007**: Your ``SECURE_BROWSER_XSS_FILTER`` setting is not set to ``True``, so your pages will not be served with an ``'X-XSS-Protection: 1; mode=block'`` header. You should consider enabling this header to activate the browser's XSS filtering and help prevent XSS diff --git a/docs/ref/middleware.txt b/docs/ref/middleware.txt index 82888ba3dab..3ca9e13114f 100644 --- a/docs/ref/middleware.txt +++ b/docs/ref/middleware.txt @@ -196,7 +196,6 @@ The ``django.middleware.security.SecurityMiddleware`` provides several security enhancements to the request/response cycle. Each one can be independently enabled or disabled with a setting. -* :setting:`SECURE_BROWSER_XSS_FILTER` * :setting:`SECURE_CONTENT_TYPE_NOSNIFF` * :setting:`SECURE_CROSS_ORIGIN_OPENER_POLICY` * :setting:`SECURE_HSTS_INCLUDE_SUBDOMAINS` @@ -422,33 +421,6 @@ setting will be useful. __ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options -.. _x-xss-protection: - -``X-XSS-Protection: 1; mode=block`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Some browsers have the ability to block content that appears to be an `XSS -attack`_. They work by looking for JavaScript content in the GET or POST -parameters of a page. If the JavaScript is replayed in the server's response, -the page is blocked from rendering and an error page is shown instead. - -The `X-XSS-Protection header`__ is used to control the operation of the -XSS filter. - -To enable the XSS filter in the browser, and force it to always block -suspected XSS attacks, you can pass the ``X-XSS-Protection: 1; mode=block`` -header. ``SecurityMiddleware`` will do this for all responses if the -:setting:`SECURE_BROWSER_XSS_FILTER` setting is ``True``. - -.. warning:: - The browser XSS filter is a useful defense measure, but must not be - relied upon exclusively. It cannot detect all XSS attacks and not all - browsers support the header. Ensure you are still :ref:`validating and - sanitizing ` all input to prevent XSS attacks. - -.. _XSS attack: https://en.wikipedia.org/wiki/Cross-site_scripting -__ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection - .. _ssl-redirect: SSL Redirect diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index f3ebee6a8de..6a568ea9b78 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -2262,20 +2262,6 @@ affect them. startproject ` creates a unique ``SECRET_KEY`` for convenience. -.. setting:: SECURE_BROWSER_XSS_FILTER - -``SECURE_BROWSER_XSS_FILTER`` ------------------------------ - -Default: ``False`` - -If ``True``, the :class:`~django.middleware.security.SecurityMiddleware` sets -the :ref:`x-xss-protection` header on all responses that do not already have it. - -Modern browsers don't honor ``X-XSS-Protection`` HTTP header anymore. Although -the setting offers little practical benefit, you may still want to set the -header if you support older browsers. - .. setting:: SECURE_CONTENT_TYPE_NOSNIFF ``SECURE_CONTENT_TYPE_NOSNIFF`` @@ -3636,7 +3622,6 @@ HTTP * :setting:`MIDDLEWARE` * Security - * :setting:`SECURE_BROWSER_XSS_FILTER` * :setting:`SECURE_CONTENT_TYPE_NOSNIFF` * :setting:`SECURE_CROSS_ORIGIN_OPENER_POLICY` * :setting:`SECURE_HSTS_INCLUDE_SUBDOMAINS` diff --git a/docs/releases/4.0.txt b/docs/releases/4.0.txt index 3f65e68c844..bf7e03fb00a 100644 --- a/docs/releases/4.0.txt +++ b/docs/releases/4.0.txt @@ -357,6 +357,24 @@ subdomains by setting :setting:`CSRF_COOKIE_DOMAIN` (or :setting:`SESSION_COOKIE_DOMAIN` if :setting:`CSRF_USE_SESSIONS` is enabled) to a value starting with a dot. +``SecurityMiddleware`` no longer sets the ``X-XSS-Protection`` header +--------------------------------------------------------------------- + +The :class:`~django.middleware.security.SecurityMiddleware` no longer sets the +``X-XSS-Protection`` header if the ``SECURE_BROWSER_XSS_FILTER`` setting is +``True``. The setting is removed. + +Most modern browsers don't honor the ``X-XSS-Protection`` HTTP header. You can +use Content-Security-Policy_ without allowing ``'unsafe-inline'`` scripts +instead. + +If you want to support legacy browsers and set the header, use this line in a +custom middleware:: + + response.headers.setdefault('X-XSS-Protection', '1; mode=block') + +.. _Content-Security-Policy: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy + Miscellaneous ------------- diff --git a/tests/middleware/test_security.py b/tests/middleware/test_security.py index 1b7434c9a8c..49432fbc8ac 100644 --- a/tests/middleware/test_security.py +++ b/tests/middleware/test_security.py @@ -175,34 +175,6 @@ class SecurityMiddlewareTest(SimpleTestCase): """ self.assertNotIn('X-Content-Type-Options', self.process_response().headers) - @override_settings(SECURE_BROWSER_XSS_FILTER=True) - def test_xss_filter_on(self): - """ - With SECURE_BROWSER_XSS_FILTER set to True, the middleware adds - "s-xss-protection: 1; mode=block" header to the response. - """ - self.assertEqual( - self.process_response().headers['X-XSS-Protection'], - '1; mode=block', - ) - - @override_settings(SECURE_BROWSER_XSS_FILTER=True) - def test_xss_filter_already_present(self): - """ - The middleware will not override an "X-XSS-Protection" header - already present in the response. - """ - response = self.process_response(secure=True, headers={"X-XSS-Protection": "foo"}) - self.assertEqual(response.headers["X-XSS-Protection"], "foo") - - @override_settings(SECURE_BROWSER_XSS_FILTER=False) - def test_xss_filter_off(self): - """ - With SECURE_BROWSER_XSS_FILTER set to False, the middleware does not - add an "X-XSS-Protection" header to the response. - """ - self.assertNotIn('X-XSS-Protection', self.process_response().headers) - @override_settings(SECURE_SSL_REDIRECT=True) def test_ssl_redirect_on(self): """