Skip to content

Commit cf2ae8c

Browse files
Rob Hudsonrobhudson
authored andcommitted
Fix #231: report percentage of 100% should always report
This also updates the RateLimited CSPMiddleware to remove both `report-uri` and `report-to` directives based on report percentage.
1 parent ed0b7a4 commit cf2ae8c

2 files changed

Lines changed: 32 additions & 6 deletions

File tree

csp/contrib/rate_limiting.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,14 @@ def build_policy(self, request: HttpRequest, response: HttpResponseBase) -> str:
2828
return ""
2929

3030
report_percentage = policy.get("REPORT_PERCENTAGE", 100)
31-
include_report_uri = random.randint(0, 100) < report_percentage
32-
if not include_report_uri:
33-
replace["report-uri"] = None
31+
remove_report = random.randint(0, 99) >= report_percentage
32+
if remove_report:
33+
replace.update(
34+
{
35+
"report-uri": None,
36+
"report-to": None,
37+
}
38+
)
3439

3540
return build_policy(config=config, update=update, replace=replace, nonce=nonce)
3641

@@ -46,8 +51,13 @@ def build_policy_ro(self, request: HttpRequest, response: HttpResponseBase) -> s
4651
return ""
4752

4853
report_percentage = policy.get("REPORT_PERCENTAGE", 100)
49-
include_report_uri = random.randint(0, 100) < report_percentage
50-
if not include_report_uri:
51-
replace["report-uri"] = None
54+
remove_report = random.randint(0, 99) >= report_percentage
55+
if remove_report:
56+
replace.update(
57+
{
58+
"report-uri": None,
59+
"report-to": None,
60+
}
61+
)
5262

5363
return build_policy(config=config, update=update, replace=replace, nonce=nonce, report_only=True)

csp/tests/test_contrib.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,26 @@ def test_report_percentage() -> None:
1919
mw.process_response(request, response)
2020
if "report-uri" in response[HEADER]:
2121
times_seen += 1
22+
if "report-to" in response[HEADER]:
23+
times_seen += 1
2224
# Roughly 10%
2325
assert 400 <= times_seen <= 600
2426

2527

28+
@override_settings(CONTENT_SECURITY_POLICY={"REPORT_PERCENTAGE": 100, "DIRECTIVES": {"report-uri": "x"}})
29+
def test_report_percentage_100() -> None:
30+
times_seen = 0
31+
for _ in range(1000):
32+
request = rf.get("/")
33+
response = HttpResponse()
34+
mw.process_response(request, response)
35+
if "report-uri" in response[HEADER]:
36+
times_seen += 1
37+
if "report-to" in response[HEADER]:
38+
times_seen += 1
39+
assert times_seen == 1000
40+
41+
2642
@override_settings(CONTENT_SECURITY_POLICY_REPORT_ONLY={"REPORT_PERCENTAGE": 10, "DIRECTIVES": {"report-uri": "x"}})
2743
def test_report_percentage_report_only() -> None:
2844
times_seen = 0

0 commit comments

Comments
 (0)