From 99f2a15404a15cabceef709dd48634bd1107cf99 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Wed, 16 Sep 2026 12:26:03 +0200 Subject: [PATCH] feat(pii): Scrub chunked cookies This extends the regex that detects sensitive cookies to also cover variants suffixed with numbers, as in `session__17`. Caveat: This only works for cookies sent as an array or string, not for cookies sent in individual keys, because there is no mechanism for glob- or pattern-based selectors. Fixes RELAY-281. Fixes #6389. --- CHANGELOG.md | 6 ++ relay-pii/src/convert.rs | 6 +- relay-pii/src/regexes.rs | 2 +- ...elay_pii__convert__tests__span_cookie.snap | 55 +++++++++++++------ ...y_pii__convert__tests__span_v2_cookie.snap | 28 ++++++++-- 5 files changed, 70 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1da36c2d6d8..034f716dc2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +**Features**: + +- Scrub numbered variants of sensitive cookies. ([#6392](https://github.com/getsentry/relay/pull/6392)) + ## 26.9.0 **Breaking Changes**: diff --git a/relay-pii/src/convert.rs b/relay-pii/src/convert.rs index 98a4f5f6123..674d27a826e 100644 --- a/relay-pii/src/convert.rs +++ b/relay-pii/src/convert.rs @@ -1693,7 +1693,7 @@ THd+9FBxiHLGXNKhG/FRSyREXEt+NyYIf/0cyByc9tNksat794ddUqnLOg0vwSkv "contexts": { "trace": { "data": { - "http.request.header.cookie": "baz=quux; session=foobar; language=en; csrf=u32t4o3tb3gg43; foo=bar", + "http.request.header.cookie": "baz=quux; session__0=foobar; language=en; csrf=u32t4o3tb3gg43; foo=bar", "http.request.header.cookie.sentrysid": "foobar", "http.request.header.cookie.sudo": "foobar", "http.request.header.cookie.su": "foobar", @@ -1723,7 +1723,7 @@ THd+9FBxiHLGXNKhG/FRSyREXEt+NyYIf/0cyByc9tNksat794ddUqnLOg0vwSkv }, "spans": [{ "data": { - "http.request.header.cookie": "session=foobar", + "http.request.header.cookie": ["baz=quux", "session__0=foobar", "language=en", "csrf=u32t4o3tb3gg43", "foo=bar"], "http.request.header.cookie.sentrysid": "foobar", "http.request.header.cookie.sudo": "foobar", "http.request.header.cookie.su": "foobar", @@ -1764,7 +1764,7 @@ THd+9FBxiHLGXNKhG/FRSyREXEt+NyYIf/0cyByc9tNksat794ddUqnLOg0vwSkv let mut data = SpanV2::from_value( serde_json::json!({ "attributes": { - "http.request.header.cookie": {"value": ["session=foobar", "language=en"]}, + "http.request.header.cookie": {"value": ["baz=quux", "session__0=foobar", "language=en", "csrf=u32t4o3tb3gg43", "foo=bar"]}, "http.request.header.cookie.sentrysid": {"value": "foobar"}, "http.request.header.cookie.sudo": {"value": "foobar"}, "http.request.header.cookie.su": {"value": "foobar"}, diff --git a/relay-pii/src/regexes.rs b/relay-pii/src/regexes.rs index 5de75902205..77e7e88977d 100644 --- a/relay-pii/src/regexes.rs +++ b/relay-pii/src/regexes.rs @@ -175,7 +175,7 @@ pub static SENSITIVE_COOKIE_NAMES: &[&str] = &[ static COOKIE_REGEX: LazyLock = LazyLock::new(|| { let variants = SENSITIVE_COOKIE_NAMES.join("|"); - let r = format!("(?i)\\b(?:{variants})=([^;]+)"); + let r = format!("(?i)\\b(?:(?:{variants})(?:__\\d+)?)=([^;]+)"); Regex::new(&r).unwrap() }); diff --git a/relay-pii/src/snapshots/relay_pii__convert__tests__span_cookie.snap b/relay-pii/src/snapshots/relay_pii__convert__tests__span_cookie.snap index 7bfb47241d2..f36d2e17d52 100644 --- a/relay-pii/src/snapshots/relay_pii__convert__tests__span_cookie.snap +++ b/relay-pii/src/snapshots/relay_pii__convert__tests__span_cookie.snap @@ -6,7 +6,7 @@ expression: data "contexts": { "trace": { "data": { - "http.request.header.cookie": "baz=quux; session=[Filtered]; language=en; csrf=[Filtered]; foo=bar", + "http.request.header.cookie": "baz=quux; session__0=[Filtered]; language=en; csrf=[Filtered]; foo=bar", "http.request.header.cookie.__session": "[Filtered]", "http.request.header.cookie._csrf": "[Filtered]", "http.request.header.cookie._iris_csrf": "[Filtered]", @@ -37,7 +37,13 @@ expression: data "spans": [ { "data": { - "http.request.header.cookie": "session=[Filtered]", + "http.request.header.cookie": [ + "baz=quux", + "session__0=[Filtered]", + "language=en", + "csrf=[Filtered]", + "foo=bar" + ], "http.request.header.cookie.__session": "[Filtered]", "http.request.header.cookie._csrf": "[Filtered]", "http.request.header.cookie._iris_csrf": "[Filtered]", @@ -74,17 +80,17 @@ expression: data [ "@cookies:filter", "s", - 18, - 28 + 21, + 31 ], [ "@cookies:filter", "s", - 48, - 58 + 51, + 61 ] ], - "len": 67 + "len": 70 } }, "http.request.header.cookie.__session": { @@ -380,16 +386,31 @@ expression: data "0": { "data": { "http.request.header.cookie": { - "": { - "rem": [ - [ - "@cookies:filter", - "s", - 8, - 18 - ] - ], - "len": 14 + "1": { + "": { + "rem": [ + [ + "@cookies:filter", + "s", + 11, + 21 + ] + ], + "len": 17 + } + }, + "3": { + "": { + "rem": [ + [ + "@cookies:filter", + "s", + 5, + 15 + ] + ], + "len": 19 + } } }, "http.request.header.cookie.__session": { diff --git a/relay-pii/src/snapshots/relay_pii__convert__tests__span_v2_cookie.snap b/relay-pii/src/snapshots/relay_pii__convert__tests__span_v2_cookie.snap index f9c1c609a29..fa5a5163ba0 100644 --- a/relay-pii/src/snapshots/relay_pii__convert__tests__span_v2_cookie.snap +++ b/relay-pii/src/snapshots/relay_pii__convert__tests__span_v2_cookie.snap @@ -6,8 +6,11 @@ expression: data "attributes": { "http.request.header.cookie": { "value": [ - "session=[Filtered]", - "language=en" + "baz=quux", + "session__0=[Filtered]", + "language=en", + "csrf=[Filtered]", + "foo=bar" ] }, "http.request.header.cookie.__session": { @@ -84,17 +87,30 @@ expression: data "attributes": { "http.request.header.cookie": { "value": { - "0": { + "1": { "": { "rem": [ [ "@cookies:filter", "s", - 8, - 18 + 11, + 21 ] ], - "len": 14 + "len": 17 + } + }, + "3": { + "": { + "rem": [ + [ + "@cookies:filter", + "s", + 5, + 15 + ] + ], + "len": 19 } } }