mirror of
https://github.com/django/django.git
synced 2025-10-24 22:26:08 +00:00
Fixed #15727 -- Added Content Security Policy (CSP) support.
This initial work adds a pair of settings to configure specific CSP directives for enforcing or reporting policy violations, a new `django.middleware.csp.ContentSecurityPolicyMiddleware` to apply the appropriate headers to responses, and a context processor to support CSP nonces in templates for safely inlining assets. Relevant documentation has been added for the 6.0 release notes, security overview, a new how-to page, and a dedicated reference section. Thanks to the multiple reviewers for their precise and valuable feedback. Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import itertools
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.checks.messages import Error, Warning
|
||||
from django.core.checks.security import base, csrf, sessions
|
||||
@@ -678,3 +680,54 @@ class CheckCrossOriginOpenerPolicyTest(SimpleTestCase):
|
||||
)
|
||||
def test_with_invalid_coop(self):
|
||||
self.assertEqual(base.check_cross_origin_opener_policy(None), [base.E024])
|
||||
|
||||
|
||||
class CheckSecureCSPTests(SimpleTestCase):
|
||||
"""Tests for the CSP settings check function."""
|
||||
|
||||
def test_secure_csp_allowed_values(self):
|
||||
"""Check should pass when both CSP settings are None or dicts."""
|
||||
allowed_values = (None, {}, {"key": "value"})
|
||||
combinations = itertools.product(allowed_values, repeat=2)
|
||||
for csp_value, csp_report_only_value in combinations:
|
||||
with (
|
||||
self.subTest(
|
||||
csp_value=csp_value, csp_report_only_value=csp_report_only_value
|
||||
),
|
||||
self.settings(
|
||||
SECURE_CSP=csp_value, SECURE_CSP_REPORT_ONLY=csp_report_only_value
|
||||
),
|
||||
):
|
||||
errors = base.check_csp_settings(None)
|
||||
self.assertEqual(errors, [])
|
||||
|
||||
def test_secure_csp_invalid_values(self):
|
||||
"""Check should fail when either CSP setting is not a dict."""
|
||||
for value in (
|
||||
False,
|
||||
True,
|
||||
0,
|
||||
42,
|
||||
"",
|
||||
"not-a-dict",
|
||||
set(),
|
||||
{"a", "b"},
|
||||
[],
|
||||
[1, 2, 3, 4],
|
||||
):
|
||||
with self.subTest(value=value):
|
||||
csp_error = Error(
|
||||
base.E026.msg % ("SECURE_CSP", value), id=base.E026.id
|
||||
)
|
||||
with self.settings(SECURE_CSP=value):
|
||||
errors = base.check_csp_settings(None)
|
||||
self.assertEqual(errors, [csp_error])
|
||||
csp_report_only_error = Error(
|
||||
base.E026.msg % ("SECURE_CSP_REPORT_ONLY", value), id=base.E026.id
|
||||
)
|
||||
with self.settings(SECURE_CSP_REPORT_ONLY=value):
|
||||
errors = base.check_csp_settings(None)
|
||||
self.assertEqual(errors, [csp_report_only_error])
|
||||
with self.settings(SECURE_CSP=value, SECURE_CSP_REPORT_ONLY=value):
|
||||
errors = base.check_csp_settings(None)
|
||||
self.assertEqual(errors, [csp_error, csp_report_only_error])
|
||||
|
||||
Reference in New Issue
Block a user