🐛 honor strictest allowUntrustedEvents policy in XHR observable#4604
🐛 honor strictest allowUntrustedEvents policy in XHR observable#4604thomas-lebeau wants to merge 1 commit into
Conversation
Bundles Sizes Evolution
🚀 CPU Performance
🧠 Memory Performance
|
🎉 All green!❄️ No new flaky tests detected 🎯 Code Coverage (details) 🔗 Commit SHA: ad75fb2 | Docs | Datadog PR Page | Give us feedback! |
a70315f to
3fdfac1
Compare
The XHR observable is a singleton initialized by the first caller. In v7,
bufferedData calls `initXhrObservable({ allowUntrustedEvents: true })` early
during SDK setup, before the customer config is parsed. The later
`initXhrObservable(configuration)` call from rum-core's requestCollection
silently reused that singleton — discarding the customer's stricter
`allowUntrustedEvents: false`. As a result, application code dispatching
synthetic `loadend` events could be reported as completed XHRs (fake
resources/network errors) even when the customer disabled untrusted events.
Track every caller's policy and evaluate the strictest (every must allow)
at event time. Mirrors the per-subscriber pattern used by initFetchObservable.
3fdfac1 to
ad75fb2
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ad75fb274f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (configuration.allowUntrustedEvents !== undefined) { | ||
| allowUntrustedEvents = configuration.allowUntrustedEvents | ||
| } |
There was a problem hiding this comment.
Preserve opt-out when a later caller opts in
When any later caller passes { allowUntrustedEvents: true }, this assignment overwrites a prior customer opt-out, so XHRs sent after that point capture true in the loadend listener and synthetic loadend events are accepted. This can happen, for example, if RUM has already initialized with the default false and another SDK/public API starts buffering data later (startBufferingData() calls initXhrObservable({ allowUntrustedEvents: true })); the stricter policy is then lost until another false call happens, contrary to the singleton needing to honor all subscribers' policies.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
it's fine, it's not expected to have the SDK initialize more that once
Motivation
Addresses a P2 review comment on #4425.
initXhrObservableis a singleton initialized by its first caller. In v7,bufferedData.tscalls it during early SDK setup with{ allowUntrustedEvents: true }— well before the customer configuration is available. The subsequentinitXhrObservable(configuration)call fromrum-core/requestCollection.tssilently reused the existing singleton, discarding the customer's stricterallowUntrustedEvents: false(the default).As a result, application code that dispatches synthetic
loadendevents on anXMLHttpRequestcould be reported as completed XHRs (fake resources / network errors) even for customers who never enabled untrusted events.Changes
packages/core/src/browser/xhrObservable.ts: track every caller'sallowUntrustedEventspolicy in a module-level array. The trust filter in theloadendlistener now evaluates the strictest policy (every caller must allow) at event time. This mirrors the per-subscriber pattern already used byinitFetchObservable'sresponseBodyActionGetters.packages/core/src/browser/xhrObservable.spec.ts: two new tests covering the conflicting-policy scenario — one verifies that an untrustedloadendis filtered when the customer disallows it (the bug), and one verifies that it passes through when every caller allows it.Scope nuance: the trust filter only gates the
loadendfallback listener. The primary completion path viaonreadystatechangeinstrumentation is unaffected (it's function-call interception, not a DOM event). Fetch is unaffected —initFetchObservabledoesn't take a trust parameter.Test instructions
yarn test:unit --spec packages/core/src/browser/xhrObservable.spec.ts— the two new tests underwith conflicting allowUntrustedEvents policies across callerspass. RevertingxhrObservable.tstomain(singleton-only) makes the "does not emit completion …" test fail with a spurious completion event.yarn test:unit— full suite stays green (939 core + 1390 rum-core tests).yarn typecheck/yarn lintclean.Checklist