Uh oh!
There was an error while loading. Please reload this page.
feat(core)!: Make tracePropagationTargets matching case-insensitive - #23534
Conversation
String and regex entries in `tracePropagationTargets` now match the outgoing request URL regardless of casing. Previously the casing had to match exactly. In browsers the URL is normalized with `new URL()` first, which lower-cases the origin, so `'myApi.com'` or `/^myApi\.com/` could never match a request to `https://myApi.com`. Keep this to a dedicated matcher in core instead of changing `isMatchingPattern`, which also backs `ignoreErrors`, `denyUrls` and `ignoreTransactions`. Also drop the `g`/`y` flags on target regexes, which make `test()` stateful, so `/myApi\.com/g` previously matched only every other request. Fixes#16018 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Note the new behaviour in the `tracePropagationTargets` JSDoc that users see in their editor, and scope the migration guide example to browsers. Server SDKs match against the raw URL, so a target matching the request's casing did work there in v10. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
size-limit report 📦
|
…s` tests CodeQL's js/incomplete-hostname-regexp flagged 16 new high-severity alerts on the test fixtures added in this branch: patterns like `/^https:\/\/myapi\.com/` and `'myapi.com'` also match `https://myapi.com.evil.com`. The rule is right to flag these. `tracePropagationTargets` decides which outgoing requests receive `sentry-trace` and `baggage` headers, so an unterminated target leaks trace context to unintended hosts, and these fixtures are what users copy. Terminate the host portion of each fixture. The assertions cover casing, not anchoring, so this does not weaken them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
The `g`-flag regression test still used a pattern with no leading anchor, which CodeQL flagged because arbitrary hosts can precede it. Anchoring it keeps the test's purpose intact: with `g` preserved the anchored pattern still fails the second call, because `test()` resumes from `lastIndex` where `^` can no longer match. Verified by reverting the flag-stripping, which fails this test alone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ake-tracepropagationtargets-matching-case-insensitive
…gets-matching-case-insensitive
bughansl run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e768fb2. Configure here.
…lifecycle The new suites were copied from neighbouring ones that pin `traceLifecycle: 'static'`, so they covered the non-default path. Span streaming is the default in v11, which is what these should exercise. The node envelope assertion moves from `transaction` to `span`, since streaming emits span v2 items rather than transaction events. Both suites were re-confirmed to fail without the fix under streaming. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…case-insensitive' of https://github.com/getsentry/sentry-javascript into charlygomez/js-4-make-tracepropagationtargets-matching-case-insensitive
…gets-matching-case-insensitive
Uh oh!
There was an error while loading. Please reload this page.
`rpcTracePropagationBindings` matched binding names with `stringMatchesSomePattern`, which compares strings case-sensitively and calls `test()` on the regex as given. A target carrying the `g` or `y` flag is stateful through `lastIndex`, so it matched only every other binding lookup. The bindings now go through `matchesTracePropagationTargets`, the same matcher `tracePropagationTargets` uses since #23534. It lower-cases both sides and drops the `g`/`y` flags before testing. `matchesTracePropagationTargets` gained a `requireExactStringMatch` parameter for this, named after the same parameter on `isMatchingPattern`. Binding names need an exact string match, otherwise an entry of `DB` would also enable propagation for `MY_DB`. The new integration suite lists the bindings as `'my_durable_object'` and `/^svc_/g` while they are named `MY_DURABLE_OBJECT`, `SVC_ALPHA` and `SVC_BETA`. `SVC_BETA` is the binding a stateful `g` regex drops, because matching `SVC_ALPHA` already moved its `lastIndex` past the start of the string. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`rpcTracePropagationBindings` matched binding names with `stringMatchesSomePattern`, which compares strings case-sensitively and calls `test()` on the regex as given. A target carrying the `g` or `y` flag is stateful through `lastIndex`, so it matched only every other binding lookup. The bindings now go through `matchesTracePropagationTargets`, the same matcher `tracePropagationTargets` uses since #23534. It lower-cases both sides and drops the `g`/`y` flags before testing. `matchesTracePropagationTargets` gained a `requireExactStringMatch` parameter for this, named after the same parameter on `isMatchingPattern`. Binding names need an exact string match, otherwise an entry of `DB` would also enable propagation for `MY_DB`. The new integration suite lists the bindings as `'my_durable_object'` and `/^svc_/g` while they are named `MY_DURABLE_OBJECT`, `SVC_ALPHA` and `SVC_BETA`. `SVC_BETA` is the binding a stateful `g` regex drops, because matching `SVC_ALPHA` already moved its `lastIndex` past the start of the string. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`rpcTracePropagationBindings` matched binding names with `stringMatchesSomePattern`, which compares strings case-sensitively and calls `test()` on the regex as given. A target carrying the `g` or `y` flag is stateful through `lastIndex`, so it matched only every other binding lookup. The bindings now go through `matchesTracePropagationTargets`, the same matcher `tracePropagationTargets` uses since #23534. It lower-cases both sides and drops the `g`/`y` flags before testing. `matchesTracePropagationTargets` gained a `requireExactStringMatch` parameter for this, named after the same parameter on `isMatchingPattern`. Binding names need an exact string match, otherwise an entry of `DB` would also enable propagation for `MY_DB`. The new integration suite lists the bindings as `'my_durable_object'` and `/^svc_/g` while they are named `MY_DURABLE_OBJECT`, `SVC_ALPHA` and `SVC_BETA`. `SVC_BETA` is the binding a stateful `g` regex drops, because matching `SVC_ALPHA` already moved its `lastIndex` past the start of the string. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`rpcTracePropagationBindings` matched binding names with `stringMatchesSomePattern`, which compares strings case-sensitively and calls `test()` on the regex as given. A target carrying the `g` or `y` flag is stateful through `lastIndex`, so it matched only every other binding lookup. The bindings now go through `matchesTracePropagationTargets`, the same matcher `tracePropagationTargets` uses since #23534. It lower-cases both sides and drops the `g`/`y` flags before testing. `matchesTracePropagationTargets` gained a `requireExactStringMatch` parameter for this, named after the same parameter on `isMatchingPattern`. Binding names need an exact string match, otherwise an entry of `DB` would also enable propagation for `MY_DB`. The new integration suite lists the bindings as `'my_durable_object'` and `/^svc_/g` while they are named `MY_DURABLE_OBJECT`, `SVC_ALPHA` and `SVC_BETA`. `SVC_BETA` is the binding a stateful `g` regex drops, because matching `SVC_ALPHA` already moved its `lastIndex` past the start of the string. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ly (#23625) `rpcTracePropagationBindings` matched binding names with `stringMatchesSomePattern`, which compares strings case-sensitively and calls `test()` on the regex as given. A target carrying the `g` or `y` flag is stateful through `lastIndex`, so it matched only every other binding lookup. The bindings now go through `matchesTracePropagationTargets`, the same matcher `tracePropagationTargets` uses since #23534. It lower-cases both sides and drops the `g`/`y` flags before testing. `matchesTracePropagationTargets` gained a `requireExactStringMatch` parameter for this, named after the same parameter on `isMatchingPattern`. Binding names need an exact string match, otherwise an entry of `DB` would also enable propagation for `MY_DB`. The new integration suite lists the bindings as `'my_durable_object'` and `/^svc_/g` while they are named `MY_DURABLE_OBJECT`, `SVC_ALPHA` and `SVC_BETA`. `SVC_BETA` is the binding a stateful `g` regex drops, because matching `SVC_ALPHA` already moved its `lastIndex` past the start of the string. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
String and regex entries in
tracePropagationTargetsnow match the outgoing request URL regardless of casing.Previously the casing had to match exactly. In browsers the URL is normalized with
new URL()first, which lower cases the origin — so'myApi.com'or/^myApi\.com/could never match a request tohttps://myApi.com.Kept to a dedicated matcher in core instead of changing
isMatchingPattern, which also backsignoreErrors,denyUrlsandignoreTransactions.Also drops the
g/yflags on target regexes — they maketest()stateful, so/myApi\.com/gpreviously matched only every other request.Fixes#16018