Skip to content

Commit b55d28f

Browse files
committed
fix: remove duplicate values from CSP directives
1 parent de02b76 commit b55d28f

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

csp/tests/test_utils.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def test_default_src() -> None:
5555
policy = build_policy()
5656
policy_eq("default-src example.com example2.com", policy)
5757

58+
5859
@override_settings(CONTENT_SECURITY_POLICY={"DIRECTIVES": {"default-src": {"example.com", "example2.com"}}})
5960
def test_default_src_is_set() -> None:
6061
policy = build_policy()
@@ -337,6 +338,35 @@ def test_only_nonce_in_value() -> None:
337338
policy_eq("default-src 'nonce-abc123'", policy)
338339

339340

341+
@override_settings(CONTENT_SECURITY_POLICY={"DIRECTIVES": {"img-src": ["example.com", "example.com"]}})
342+
def test_deduplicate_values() -> None:
343+
"""
344+
GitHub issue #40 - given project settings as a tuple, and
345+
an update/replace with a string, concatenate correctly.
346+
"""
347+
policy = build_policy()
348+
policy_eq("default-src 'self'; img-src example.com", policy)
349+
350+
351+
@override_settings(CONTENT_SECURITY_POLICY={"DIRECTIVES": {"img-src": ["example.com", "example.com"]}})
352+
def test_deduplicate_values_update() -> None:
353+
"""
354+
GitHub issue #40 - given project settings as a tuple, and
355+
an update/replace with a string, concatenate correctly.
356+
"""
357+
policy = build_policy(update={"img-src": "example.com"})
358+
policy_eq("default-src 'self'; img-src example.com", policy)
359+
360+
361+
@override_settings(CONTENT_SECURITY_POLICY={"DIRECTIVES": {"img-src": ("example.com",)}})
362+
def test_deduplicate_values_replace() -> None:
363+
"""
364+
Demonstrate that GitHub issue #40 doesn't affect replacements
365+
"""
366+
policy = build_policy(replace={"img-src": ["example2.com", "example2.com"]})
367+
policy_eq("default-src 'self'; img-src example2.com", policy)
368+
369+
340370
def test_boolean_directives() -> None:
341371
for directive in ["upgrade-insecure-requests", "block-all-mixed-content"]:
342372
with override_settings(CONTENT_SECURITY_POLICY={"DIRECTIVES": {directive: True}}):

csp/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ def build_policy(
130130
# Strip the `NONCE` sentinel value if no nonce is provided.
131131
value = [v for v in value if v != NONCE]
132132

133+
value = list(dict.fromkeys(value)) # Deduplicate value without completely disturbing order
133134
policy_parts[key] = " ".join(value)
134135

135136
if report_uri:

0 commit comments

Comments
 (0)