diff --git a/CHANGELOG.md b/CHANGELOG.md index c9d3e8d56c..09a7df2f94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ **Features**: - Scrub non-minidump attachments if there are explicit `$attachment` rules. ([#4415](https://github.com/getsentry/relay/pull/4415)) +- Include blocked domain in CSP reports as a tag. ([#4435](https://github.com/getsentry/relay/pull/4435)) **Internal**: diff --git a/relay-event-schema/src/protocol/security_report.rs b/relay-event-schema/src/protocol/security_report.rs index 8c7a0e7fd5..705ba808a2 100644 --- a/relay-event-schema/src/protocol/security_report.rs +++ b/relay-event-schema/src/protocol/security_report.rs @@ -463,7 +463,7 @@ impl CspRaw { } fn get_tags(&self, effective_directive: CspDirective) -> Tags { - Tags(PairList::from(vec![ + let mut tags = vec![ Annotated::new(TagEntry( Annotated::new("effective-directive".to_string()), Annotated::new(effective_directive.to_string()), @@ -472,7 +472,18 @@ impl CspRaw { Annotated::new("blocked-uri".to_string()), Annotated::new(self.sanitized_blocked_uri()), )), - ])) + ]; + + if let Ok(url) = Url::parse(&self.blocked_uri) { + if let ("http" | "https", Some(host)) = (url.scheme(), url.host_str()) { + tags.push(Annotated::new(TagEntry( + Annotated::new("blocked-host".to_string()), + Annotated::new(host.to_owned()), + ))); + } + } + + Tags(PairList::from(tags)) } fn get_request(&self) -> Request { @@ -1251,7 +1262,7 @@ mod tests { let mut event = Event::default(); Csp::apply_to_event(json.as_bytes(), &mut event).unwrap(); - assert_annotated_snapshot!(Annotated::new(event), @r#" + assert_annotated_snapshot!(Annotated::new(event), @r###" { "culprit": "style-src cdn.example.com", "logentry": { @@ -1268,6 +1279,10 @@ mod tests { [ "blocked-uri", "http://example.com/lol.css" + ], + [ + "blocked-host", + "example.com" ] ], "csp": { @@ -1278,7 +1293,7 @@ mod tests { "violated_directive": "style-src cdn.example.com" } } - "#); + "###); } #[test] @@ -1337,7 +1352,7 @@ mod tests { let mut event = Event::default(); Csp::apply_to_event(json.as_bytes(), &mut event).unwrap(); - assert_annotated_snapshot!(Annotated::new(event), @r#" + assert_annotated_snapshot!(Annotated::new(event), @r###" { "culprit": "default-src self", "logentry": { @@ -1360,6 +1375,10 @@ mod tests { [ "blocked-uri", "http://evilhackerscripts.com" + ], + [ + "blocked-host", + "evilhackerscripts.com" ] ], "csp": { @@ -1371,7 +1390,7 @@ mod tests { "violated_directive": "default-src self" } } - "#); + "###); } #[test] @@ -1396,7 +1415,7 @@ mod tests { let mut event = Event::default(); Csp::apply_to_event(json.as_bytes(), &mut event).unwrap(); - assert_annotated_snapshot!(Annotated::new(event), @r#" + assert_annotated_snapshot!(Annotated::new(event), @r###" { "culprit": "script-src", "logentry": { @@ -1419,6 +1438,10 @@ mod tests { [ "blocked-uri", "http://baddomain.com/test.js?_=1515535030116" + ], + [ + "blocked-host", + "baddomain.com" ] ], "csp": { @@ -1436,7 +1459,7 @@ mod tests { "disposition": "enforce" } } - "#); + "###); } #[test] @@ -1559,7 +1582,7 @@ mod tests { let mut event = Event::default(); Csp::apply_to_event(json.as_bytes(), &mut event).unwrap(); - insta::assert_debug_snapshot!(event.tags, @r#" + insta::assert_debug_snapshot!(event.tags, @r###" Tags( PairList( [ @@ -1571,10 +1594,14 @@ mod tests { "blocked-uri", "https://api.stripe.com/v1/tokens", ), + TagEntry( + "blocked-host", + "api.stripe.com", + ), ], ), ) - "#); + "###); } #[test] diff --git a/tests/integration/fixtures/security_report/csp.no_processing.output.json b/tests/integration/fixtures/security_report/csp.no_processing.output.json index b8aa10746d..32589fdaa2 100644 --- a/tests/integration/fixtures/security_report/csp.no_processing.output.json +++ b/tests/integration/fixtures/security_report/csp.no_processing.output.json @@ -58,6 +58,10 @@ [ "blocked-uri", "http://evilhackerscripts.com" + ], + [ + "blocked-host", + "evilhackerscripts.com" ] ], "user": { diff --git a/tests/integration/fixtures/security_report/csp.normalized.output.json b/tests/integration/fixtures/security_report/csp.normalized.output.json index 6c3f3ea898..746e911442 100644 --- a/tests/integration/fixtures/security_report/csp.normalized.output.json +++ b/tests/integration/fixtures/security_report/csp.normalized.output.json @@ -49,6 +49,10 @@ [ "blocked-uri", "http://evilhackerscripts.com" + ], + [ + "blocked-host", + "evilhackerscripts.com" ] ], "key_id": "123", diff --git a/tests/integration/fixtures/security_report/csp_chrome_blocked_asset.no_processing.output.json b/tests/integration/fixtures/security_report/csp_chrome_blocked_asset.no_processing.output.json index c471307285..15b0650c5e 100644 --- a/tests/integration/fixtures/security_report/csp_chrome_blocked_asset.no_processing.output.json +++ b/tests/integration/fixtures/security_report/csp_chrome_blocked_asset.no_processing.output.json @@ -55,6 +55,10 @@ [ "blocked-uri", "http://notlocalhost:8000/lol.css" + ], + [ + "blocked-host", + "notlocalhost" ] ], "user": { diff --git a/tests/integration/fixtures/security_report/csp_firefox_blocked_asset.no_processing.output.json b/tests/integration/fixtures/security_report/csp_firefox_blocked_asset.no_processing.output.json index fd1a2f839e..ab07f668f7 100644 --- a/tests/integration/fixtures/security_report/csp_firefox_blocked_asset.no_processing.output.json +++ b/tests/integration/fixtures/security_report/csp_firefox_blocked_asset.no_processing.output.json @@ -54,6 +54,10 @@ [ "blocked-uri", "http://notlocalhost:8000/lol.css" + ], + [ + "blocked-host", + "notlocalhost" ] ], "user": {