diff --git a/django/core/checks/security/base.py b/django/core/checks/security/base.py index bc804c53df5..2f8a0f11ee7 100644 --- a/django/core/checks/security/base.py +++ b/django/core/checks/security/base.py @@ -45,7 +45,7 @@ W005 = Warning( W006 = Warning( "Your SECURE_CONTENT_TYPE_NOSNIFF setting is not set to True, " "so your pages will not be served with an " - "'x-content-type-options: nosniff' header. " + "'X-Content-Type-Options: nosniff' header. " "You should consider enabling this header to prevent the " "browser from identifying content types incorrectly.", id='security.W006', @@ -54,7 +54,7 @@ W006 = Warning( W007 = Warning( "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. " + "'X-XSS-Protection: 1; mode=block' header. " "You should consider enabling this header to activate the " "browser's XSS filtering and help prevent XSS attacks.", id='security.W007', diff --git a/django/middleware/security.py b/django/middleware/security.py index 296567432f7..dfca3b64de9 100644 --- a/django/middleware/security.py +++ b/django/middleware/security.py @@ -29,18 +29,18 @@ class SecurityMiddleware(MiddlewareMixin): def process_response(self, request, response): if (self.sts_seconds and request.is_secure() and - 'strict-transport-security' not in response): + 'Strict-Transport-Security' not in response): sts_header = "max-age=%s" % self.sts_seconds if self.sts_include_subdomains: sts_header = sts_header + "; includeSubDomains" if self.sts_preload: sts_header = sts_header + "; preload" - response["strict-transport-security"] = sts_header + response['Strict-Transport-Security'] = sts_header if self.content_type_nosniff: - response.setdefault('x-content-type-options', 'nosniff') + response.setdefault('X-Content-Type-Options', 'nosniff') if self.xss_filter: - response.setdefault('x-xss-protection', '1; mode=block') + response.setdefault('X-XSS-Protection', '1; mode=block') return response diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index dd74639d33d..0173f437d08 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -347,11 +347,11 @@ The following checks are run if you use the :option:`check --deploy` option: your domain should be served exclusively via SSL. * **security.W006**: Your :setting:`SECURE_CONTENT_TYPE_NOSNIFF` setting is not set to ``True``, so your pages will not be served with an - ``'x-content-type-options: nosniff'`` header. You should consider enabling + ``'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 set to ``True``, so your pages will not be served with an - ``'x-xss-protection: 1; mode=block'`` header. You should consider enabling + ``'X-XSS-Protection: 1; mode=block'`` header. You should consider enabling this header to activate the browser's XSS filtering and help prevent XSS attacks. * **security.W008**: Your :setting:`SECURE_SSL_REDIRECT` setting is not set to diff --git a/tests/middleware/test_security.py b/tests/middleware/test_security.py index eaefb22ee4d..97ea0c3f6ee 100644 --- a/tests/middleware/test_security.py +++ b/tests/middleware/test_security.py @@ -44,117 +44,117 @@ class SecurityMiddlewareTest(SimpleTestCase): def test_sts_on(self): """ With HSTS_SECONDS=3600, the middleware adds - "strict-transport-security: max-age=3600" to the response. + "Strict-Transport-Security: max-age=3600" to the response. """ self.assertEqual( - self.process_response(secure=True)["strict-transport-security"], + self.process_response(secure=True)["Strict-Transport-Security"], 'max-age=3600', ) @override_settings(SECURE_HSTS_SECONDS=3600) def test_sts_already_present(self): """ - The middleware will not override a "strict-transport-security" header + The middleware will not override a "Strict-Transport-Security" header already present in the response. """ response = self.process_response( secure=True, - headers={"strict-transport-security": "max-age=7200"}) - self.assertEqual(response["strict-transport-security"], "max-age=7200") + headers={"Strict-Transport-Security": "max-age=7200"}) + self.assertEqual(response["Strict-Transport-Security"], "max-age=7200") @override_settings(HSTS_SECONDS=3600) def test_sts_only_if_secure(self): """ - The "strict-transport-security" header is not added to responses going + The "Strict-Transport-Security" header is not added to responses going over an insecure connection. """ - self.assertNotIn("strict-transport-security", self.process_response(secure=False)) + self.assertNotIn("Strict-Transport-Security", self.process_response(secure=False)) @override_settings(HSTS_SECONDS=0) def test_sts_off(self): """ With HSTS_SECONDS of 0, the middleware does not add a - "strict-transport-security" header to the response. + "Strict-Transport-Security" header to the response. """ - self.assertNotIn("strict-transport-security", self.process_response(secure=True)) + self.assertNotIn("Strict-Transport-Security", self.process_response(secure=True)) @override_settings( SECURE_HSTS_SECONDS=600, SECURE_HSTS_INCLUDE_SUBDOMAINS=True) def test_sts_include_subdomains(self): """ With HSTS_SECONDS non-zero and HSTS_INCLUDE_SUBDOMAINS - True, the middleware adds a "strict-transport-security" header with the + True, the middleware adds a "Strict-Transport-Security" header with the "includeSubDomains" directive to the response. """ response = self.process_response(secure=True) - self.assertEqual(response["strict-transport-security"], "max-age=600; includeSubDomains") + self.assertEqual(response["Strict-Transport-Security"], "max-age=600; includeSubDomains") @override_settings( SECURE_HSTS_SECONDS=600, SECURE_HSTS_INCLUDE_SUBDOMAINS=False) def test_sts_no_include_subdomains(self): """ With HSTS_SECONDS non-zero and HSTS_INCLUDE_SUBDOMAINS - False, the middleware adds a "strict-transport-security" header without + False, the middleware adds a "Strict-Transport-Security" header without the "includeSubDomains" directive to the response. """ response = self.process_response(secure=True) - self.assertEqual(response["strict-transport-security"], "max-age=600") + self.assertEqual(response["Strict-Transport-Security"], "max-age=600") @override_settings(SECURE_HSTS_SECONDS=10886400, SECURE_HSTS_PRELOAD=True) def test_sts_preload(self): """ With HSTS_SECONDS non-zero and SECURE_HSTS_PRELOAD True, the middleware - adds a "strict-transport-security" header with the "preload" directive + adds a "Strict-Transport-Security" header with the "preload" directive to the response. """ response = self.process_response(secure=True) - self.assertEqual(response["strict-transport-security"], "max-age=10886400; preload") + self.assertEqual(response["Strict-Transport-Security"], "max-age=10886400; preload") @override_settings(SECURE_HSTS_SECONDS=10886400, SECURE_HSTS_INCLUDE_SUBDOMAINS=True, SECURE_HSTS_PRELOAD=True) def test_sts_subdomains_and_preload(self): """ With HSTS_SECONDS non-zero, SECURE_HSTS_INCLUDE_SUBDOMAINS and - SECURE_HSTS_PRELOAD True, the middleware adds a "strict-transport-security" + SECURE_HSTS_PRELOAD True, the middleware adds a "Strict-Transport-Security" header containing both the "includeSubDomains" and "preload" directives to the response. """ response = self.process_response(secure=True) - self.assertEqual(response["strict-transport-security"], "max-age=10886400; includeSubDomains; preload") + self.assertEqual(response["Strict-Transport-Security"], "max-age=10886400; includeSubDomains; preload") @override_settings(SECURE_HSTS_SECONDS=10886400, SECURE_HSTS_PRELOAD=False) def test_sts_no_preload(self): """ With HSTS_SECONDS non-zero and SECURE_HSTS_PRELOAD - False, the middleware adds a "strict-transport-security" header without + False, the middleware adds a "Strict-Transport-Security" header without the "preload" directive to the response. """ response = self.process_response(secure=True) - self.assertEqual(response["strict-transport-security"], "max-age=10886400") + self.assertEqual(response["Strict-Transport-Security"], "max-age=10886400") @override_settings(SECURE_CONTENT_TYPE_NOSNIFF=True) def test_content_type_on(self): """ With CONTENT_TYPE_NOSNIFF set to True, the middleware adds - "x-content-type-options: nosniff" header to the response. + "X-Content-Type-Options: nosniff" header to the response. """ - self.assertEqual(self.process_response()["x-content-type-options"], "nosniff") + self.assertEqual(self.process_response()["X-Content-Type-Options"], "nosniff") @override_settings(SECURE_CONTENT_TYPE_NOSNIFF=True) def test_content_type_already_present(self): """ - The middleware will not override an "x-content-type-options" header + The middleware will not override an "X-Content-Type-Options" header already present in the response. """ - response = self.process_response(secure=True, headers={"x-content-type-options": "foo"}) - self.assertEqual(response["x-content-type-options"], "foo") + response = self.process_response(secure=True, headers={"X-Content-Type-Options": "foo"}) + self.assertEqual(response["X-Content-Type-Options"], "foo") @override_settings(SECURE_CONTENT_TYPE_NOSNIFF=False) def test_content_type_off(self): """ With CONTENT_TYPE_NOSNIFF False, the middleware does not add an - "x-content-type-options" header to the response. + "X-Content-Type-Options" header to the response. """ - self.assertNotIn("x-content-type-options", self.process_response()) + self.assertNotIn("X-Content-Type-Options", self.process_response()) @override_settings(SECURE_BROWSER_XSS_FILTER=True) def test_xss_filter_on(self): @@ -163,25 +163,25 @@ class SecurityMiddlewareTest(SimpleTestCase): "s-xss-protection: 1; mode=block" header to the response. """ self.assertEqual( - self.process_response()["x-xss-protection"], + self.process_response()["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 + 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["x-xss-protection"], "foo") + response = self.process_response(secure=True, headers={"X-XSS-Protection": "foo"}) + self.assertEqual(response["X-XSS-Protection"], "foo") @override_settings(BROWSER_XSS_FILTER=False) def test_xss_filter_off(self): """ With BROWSER_XSS_FILTER set to False, the middleware does not add an - "x-xss-protection" header to the response. + "X-XSS-Protection" header to the response. """ - self.assertNotIn("x-xss-protection", self.process_response()) + self.assertNotIn("X-XSS-Protection", self.process_response()) @override_settings(SECURE_SSL_REDIRECT=True) def test_ssl_redirect_on(self):