diff --git a/lib/crates/fabro-server/src/security_headers.rs b/lib/crates/fabro-server/src/security_headers.rs index 16848699e..9963fa43d 100644 --- a/lib/crates/fabro-server/src/security_headers.rs +++ b/lib/crates/fabro-server/src/security_headers.rs @@ -20,9 +20,14 @@ pub async fn layer(req: Request, next: Next) -> Response { } fn apply_csp(headers: &mut HeaderMap) { + // Report-only while we tune the policy: browsers evaluate violations and log + // them to the console without blocking any resources. Switch back to the + // enforcing `content-security-policy` header once the policy is clean. if let Ok(value) = HeaderValue::from_str(csp::policy()) { headers - .entry(HeaderName::from_static("content-security-policy")) + .entry(HeaderName::from_static( + "content-security-policy-report-only", + )) .or_insert(value); } } @@ -187,11 +192,11 @@ mod tests { } #[test] - fn csp_is_enforced_not_report_only() { + fn csp_is_report_only_not_enforced() { let mut headers = HeaderMap::new(); apply_csp(&mut headers); - assert!(headers.contains_key("content-security-policy")); - assert!(!headers.contains_key("content-security-policy-report-only")); + assert!(headers.contains_key("content-security-policy-report-only")); + assert!(!headers.contains_key("content-security-policy")); } #[test] diff --git a/lib/crates/fabro-server/tests/it/api/routing.rs b/lib/crates/fabro-server/tests/it/api/routing.rs index 5a4d945f5..c2f542751 100644 --- a/lib/crates/fabro-server/tests/it/api/routing.rs +++ b/lib/crates/fabro-server/tests/it/api/routing.rs @@ -350,15 +350,15 @@ async fn security_headers_are_applied_to_all_responses() { // external module scripts. let csp = spa_response .headers() - .get("content-security-policy") - .expect("CSP header should be emitted") + .get("content-security-policy-report-only") + .expect("CSP report-only header should be emitted") .to_str() .expect("CSP should be ASCII"); assert!( !spa_response .headers() - .contains_key("content-security-policy-report-only"), - "CSP should be enforced, not report-only" + .contains_key("content-security-policy"), + "CSP should be report-only while tuning, not enforced" ); assert!(csp.contains("default-src 'self'"), "got: {csp}"); assert!(csp.contains("script-src 'self'"), "got: {csp}");