fix(core): Filter collected HTTP bodies and redact browser GraphQL document literals - #24178
fix(core): Filter collected HTTP bodies and redact browser GraphQL document literals#24178s1gr1d wants to merge 1 commit into
Conversation
| 'user-agent': expect.stringContaining(''), | ||
| 'content-type': 'text/plain', | ||
| }, | ||
| data: 'some plain text', |
There was a problem hiding this comment.
The current spec says raw bodies should be filtered: https://develop.sentry.dev/sdk/foundations/client/data-collection/#request-and-response-bodies
|
|
||
| const result: Record<string, unknown> = {}; | ||
| for (const [key, nested] of Object.entries(value)) { | ||
| result[key] = shouldFilterDataKey(key, true) ? FILTERED_VALUE : filterBodyValue(nested); |
size-limit report 📦
|
|
bugbot run |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit c943d35. Configure here.
| } | ||
|
|
||
| // The query-param filter keeps the body's original encoding byte-for-byte. | ||
| return (FORM_BODY_RE.test(body) && filterQueryParams(body, true)) || FILTERED_VALUE; |
There was a problem hiding this comment.
Form heuristic leaks unstructured bodies
Medium Severity
After JSON.parse fails to yield an object or array, any string matching FORM_BODY_RE is treated as form data and returned with keys intact. Unstructured bodies that merely contain = (base64 padding, JSON string scalars, prose) therefore keep their payload, and because the denylist only replaces values the bulk of that data is preserved as the key.
Additional Locations (1)
Triggered by project rule: PR Review Guidelines for Cursor Bot
Reviewed by Cursor Bugbot for commit c943d35. Configure here.


Automatically captured HTTP request bodies went out raw, and the browser
graphqlClientattached GraphQL documents with inline literals intact.
Bodies now run through a filter at capture time, before truncation, since a truncated JSON
body no longer parses. JSON and form bodies keep their shape, and values of sensitive keys
become
[Filtered]. A body without key-value structure is filtered wholesale, as the datacollection spec requires. The browser GraphQL document gets the same literal redaction the
server-side integration applies to the parsed AST.
The model follows OTel's sanitization of
db.query.text: keep the structure, replace the values, never send what the SDK cannot scrub.Request bodies (
event.request.data/http.request.body.data)httpBodiesdefault (on)httpBodies: [](off){"colour":"blue","password":"hunter2"}{"colour":"blue","password":"[Filtered]"}colour=blue&access_token=abc123colour=blue&access_token=[Filtered][Filtered]{"note":"xxx…...)[Filtered]"Not captured" means no attribute at all, while
[Filtered]still records that a body existed.GraphQL document (
graphql.documenton span and breadcrumb)graphQL.documentdefault (on)document: false(off)query { user(email: "jane@example.com", age: 42) { name } }query { user(email: "*", age: *) { name } }query GetUser($id: ID!) { user(id: $id) { name } }Part of #24081