Skip to content

Commit c89eb33

Browse files
committed
More specific Reporting-Endpoints csp check
1 parent 570b501 commit c89eb33

File tree

1 file changed

+31
-19
lines changed
  • plain-scan/plain/scan/audits

1 file changed

+31
-19
lines changed

plain-scan/plain/scan/audits/csp.py

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -810,17 +810,16 @@ def _check_missing_semicolon(self, csp_header: str) -> CheckResult:
810810
def _check_reporting(
811811
self, directives: dict[str, list[str]], response: requests.Response
812812
) -> CheckResult:
813-
"""Check if CSP reporting is configured with modern standards.
813+
"""Check if CSP reporting is configured with modern Reporting-Endpoints header.
814814
815-
Pushes toward Reporting-Endpoints header (90% browser support, Reporting API v1).
816-
The report-uri directive and Report-To header are deprecated.
815+
Validates that report-to endpoints exist in Reporting-Endpoints header.
816+
The report-uri directive and Report-To header are deprecated and should not be used.
817817
"""
818818
has_report_uri = "report-uri" in directives
819819
has_report_to = "report-to" in directives
820820

821-
# Check for reporting headers
822-
has_reporting_endpoints = "Reporting-Endpoints" in response.headers
823-
has_report_to_header = "Report-To" in response.headers
821+
# Check for Reporting-Endpoints header (modern, Reporting API v1)
822+
reporting_endpoints_header = response.headers.get("Reporting-Endpoints", "")
824823

825824
# No reporting configured - this is optional
826825
if not has_report_uri and not has_report_to:
@@ -835,31 +834,44 @@ def _check_reporting(
835834
return CheckResult(
836835
name="reporting",
837836
passed=False,
838-
message="CSP uses deprecated report-uri (migrate to report-to with Reporting-Endpoints header)",
837+
message="CSP uses deprecated report-uri (migrate to report-to with Reporting-Endpoints)",
839838
)
840839

841-
# Using report-to directive - check for required headers
840+
# Using report-to directive - validate the endpoint exists in Reporting-Endpoints
842841
if has_report_to:
843-
if has_reporting_endpoints:
842+
# Get the endpoint name(s) from the directive
843+
report_to_values = directives.get("report-to", [])
844+
if not report_to_values:
844845
return CheckResult(
845846
name="reporting",
846-
passed=True,
847-
message="CSP reporting correctly configured with Reporting-Endpoints",
847+
passed=False,
848+
message="CSP report-to directive is empty",
848849
)
849850

850-
if has_report_to_header:
851+
endpoint_name = report_to_values[0] # report-to should have one value
852+
853+
# Must have Reporting-Endpoints header for report-to to work
854+
if not reporting_endpoints_header:
851855
return CheckResult(
852856
name="reporting",
853857
passed=False,
854-
message="CSP uses deprecated Report-To header (migrate to Reporting-Endpoints)",
858+
message="CSP report-to directive requires Reporting-Endpoints header",
855859
)
856860

857-
# Has report-to but no corresponding header
858-
return CheckResult(
859-
name="reporting",
860-
passed=False,
861-
message="CSP report-to directive requires Reporting-Endpoints header",
862-
)
861+
# Validate endpoint exists in Reporting-Endpoints header
862+
# Format: endpoint-name="url", other="url2"
863+
if f'{endpoint_name}="' in reporting_endpoints_header:
864+
return CheckResult(
865+
name="reporting",
866+
passed=True,
867+
message="CSP reporting correctly configured with Reporting-Endpoints",
868+
)
869+
else:
870+
return CheckResult(
871+
name="reporting",
872+
passed=False,
873+
message=f"CSP report-to references '{endpoint_name}' but it's not defined in Reporting-Endpoints header",
874+
)
863875

864876
# Shouldn't reach here, but safety fallback
865877
return CheckResult(

0 commit comments

Comments
 (0)