Skip to content

Commit 4190fe4

Browse files
committed
form body additions
1 parent e93cb39 commit 4190fe4

2 files changed

Lines changed: 19 additions & 3 deletions

File tree

‎packages/core/src/utils/data-collection/filterHttpBody.ts‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,18 @@ import { FILTERED_VALUE } from './filtering-snippets';
33
import { shouldFilterDataKey } from './filterKeyValueData';
44
import { filterQueryParams } from './filterQueryParams';
55

6-
/** Matches `key=value&key2=value2` bodies, the only non-JSON shape whose keys the denylist can check. */
7-
const FORM_BODY_RE = /^[^=&]+=[^&]*(?:&[^=&]+=[^&]*)*$/;
6+
/** One `&`-separated form segment: empty, a bare key, or `key=value`. */
7+
const FORM_SEGMENT_RE = /^(?:[^=]+(?:=.*)?)?$/;
8+
9+
/**
10+
* A form body is `&`-separated `key=value` pairs, the only non-JSON shape whose keys the denylist
11+
* can check. Valueless keys, empty segments, and a trailing `&` are tolerated — a too-strict gate
12+
* would let a body like `password=secret&` skip the filter and ship raw. At least one `=` is
13+
* required so prose is never rewritten as a pseudo-form.
14+
*/
15+
function isFormBody(body: string): boolean {
16+
return body.includes('=') && body.split('&').every(segment => FORM_SEGMENT_RE.test(segment));
17+
}
818

919
/**
1020
* Scrubs the values of known-sensitive keys in an HTTP body the SDK collected itself, before it
@@ -40,7 +50,7 @@ export function filterCollectedHttpBodyString(body: string): string {
4050
// Not JSON. The form-encoded attempt below runs instead.
4151
}
4252

43-
if (FORM_BODY_RE.test(body)) {
53+
if (isFormBody(body)) {
4454
// The query-param filter keeps the body's original encoding byte-for-byte.
4555
return filterQueryParams(body, true) ?? body;
4656
}

‎packages/core/test/lib/utils/data-collection/filterHttpBody.test.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ describe('filterCollectedHttpBody', () => {
5050
it('keeps a single-field form', () => {
5151
expect(filterCollectedHttpBody('flag=on')).toBe('flag=on');
5252
});
53+
54+
it('filters forms with a trailing ampersand, valueless keys, or empty segments', () => {
55+
expect(filterCollectedHttpBody('password=secret&')).toBe('password=[Filtered]&');
56+
expect(filterCollectedHttpBody('token=abc&flag')).toBe('token=[Filtered]&flag');
57+
expect(filterCollectedHttpBody('colour=blue&&password=x')).toBe('colour=blue&&password=[Filtered]');
58+
});
5359
});
5460

5561
describe('bodies without key-value structure', () => {

0 commit comments

Comments
 (0)