🐛 don't adopt another tab's session when it replaces ours directly#4537
🐛 don't adopt another tab's session when it replaces ours directly#4537BenoitZugmeyer merged 1 commit intov7from
Conversation
When another tab's session ID appeared in the cookie while this tab still had an active session (direct ID-to-ID replacement, no intermediate isExpired state), `sessionExpired` was never set to true because the `!hasSession` guard only covered the normal expiry path. This let the current tab immediately adopt the foreign session without waiting for a user interaction.
Bundles Sizes Evolution
🚀 CPU PerformancePending... 🧠 Memory Performance
|
🎉 All green!❄️ No new flaky tests detected 🎯 Code Coverage (details) 🔗 Commit SHA: 7da2b2b | Docs | Datadog PR Page | Give us feedback! |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7da2b2b35f
ℹ️ 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 (!hasSession) { | ||
| sessionExpired = true | ||
| } | ||
| sessionExpired = true |
There was a problem hiding this comment.
Regenerate before accepting replaced sessions on activity
When another tab directly replaces the cookie with an active different id, this marks the local manager expired and skips immediate adoption, but the shared store still contains newState.id. On the next user activity in this tab, throttledExpandOrRenew resets sessionExpired = false and expandOrRenew preserves that active id, so handleStateChange will add the other tab's session instead of creating this tab's fresh session. This means the scenario described by the change still mixes sessions as soon as the user interacts unless the replaced state is first expired/ignored in storage.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
mixes sessions as soon as the user interacts unless the replaced state is first expired/ignored in storage.
This is the expected behavior
Motivation
When a tab's session was replaced by another tab's session directly (ID-to-ID, without going through an intermediate expired state), the current tab would silently adopt the foreign session and start sending events under it — without any user interaction. Users on multi-tab setups could find their session data mixed across tabs unexpectedly.
Changes
!hasSessionguard onsessionExpired = trueso that a direct session ID replacement is treated the same as a normal expiry: this tab marks itself as expired and waits for a user interaction before starting a new session.Test instructions
DD_RUM.stopSession().id=...&created=...&expire=...value.Checklist