Skip to content

Commit

Permalink
Fix #231: report percentage of 100% should always report
Browse files Browse the repository at this point in the history
This also updates the RateLimited CSPMiddleware to remove both
`report-uri` and `report-to` directives based on report percentage.
  • Loading branch information
robhudson committed Jul 11, 2024
1 parent ed0b7a4 commit cf2ae8c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
22 changes: 16 additions & 6 deletions csp/contrib/rate_limiting.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@ def build_policy(self, request: HttpRequest, response: HttpResponseBase) -> str:
return ""

report_percentage = policy.get("REPORT_PERCENTAGE", 100)
include_report_uri = random.randint(0, 100) < report_percentage
if not include_report_uri:
replace["report-uri"] = None
remove_report = random.randint(0, 99) >= report_percentage
if remove_report:
replace.update(
{
"report-uri": None,
"report-to": None,
}
)

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

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

report_percentage = policy.get("REPORT_PERCENTAGE", 100)
include_report_uri = random.randint(0, 100) < report_percentage
if not include_report_uri:
replace["report-uri"] = None
remove_report = random.randint(0, 99) >= report_percentage
if remove_report:
replace.update(
{
"report-uri": None,
"report-to": None,
}
)

return build_policy(config=config, update=update, replace=replace, nonce=nonce, report_only=True)
16 changes: 16 additions & 0 deletions csp/tests/test_contrib.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,26 @@ def test_report_percentage() -> None:
mw.process_response(request, response)
if "report-uri" in response[HEADER]:
times_seen += 1
if "report-to" in response[HEADER]:
times_seen += 1
# Roughly 10%
assert 400 <= times_seen <= 600


@override_settings(CONTENT_SECURITY_POLICY={"REPORT_PERCENTAGE": 100, "DIRECTIVES": {"report-uri": "x"}})
def test_report_percentage_100() -> None:
times_seen = 0
for _ in range(1000):
request = rf.get("/")
response = HttpResponse()
mw.process_response(request, response)
if "report-uri" in response[HEADER]:
times_seen += 1
if "report-to" in response[HEADER]:
times_seen += 1
assert times_seen == 1000


@override_settings(CONTENT_SECURITY_POLICY_REPORT_ONLY={"REPORT_PERCENTAGE": 10, "DIRECTIVES": {"report-uri": "x"}})
def test_report_percentage_report_only() -> None:
times_seen = 0
Expand Down

0 comments on commit cf2ae8c

Please sign in to comment.