October 25, 2026
$11,000 for Two Login Flows That Shared a Memory: A Session Puzzling Bug That Skipped MFA Entirely
Some of the hardest bugs to find aren’t hidden in any single endpoint at all — they live in the gap between two features that were each…

By T4nv1
5 min read
Some of the hardest bugs to find aren't hidden in any single endpoint at all — they live in the gap between two features that were each tested thoroughly on their own, by different people, at different times, neither of whom had reason to think about what happens when a user's session touches both flows in an order nobody anticipated. This one took real patience to find, and it only came together after I started treating the application's session state as its own object worth mapping, rather than testing each login-related feature as an island.
The target, which I'll call Driftcode here per their program's terms, is an enterprise HR platform supporting both standard password login with mandatory MFA, and a separate, less commonly used SSO login path for customers using corporate identity providers.
Why I Started Looking at Session State Specifically
Having spent a while testing both login flows independently — each one solid on its own, MFA properly enforced on the password path, SSO properly validated on its path — I switched to a different, more deliberate approach for this stage: rather than testing each flow start-to-finish in isolation, I started a password login, stopped deliberately right after submitting correct credentials but before completing the MFA step, and then, in the same browser session, started an entirely separate SSO login attempt to see what the application's session state actually looked like in that partial, in-between condition.
I'll be honest that an LLM played a small, specific role in planning this test, not executing it: I described the two flows and asked for a structured list of "interesting intermediate states" worth testing — points where a user might plausibly abandon one flow partway through and start another, given the application's actual UI structure. That's a reasonably creative enumeration task, and it surfaced a short list of scenarios worth trying by hand, including the specific one that turned out to matter: an in-progress, MFA-pending password login session, followed by initiating SSO. I want to be clear that the model didn't find the vulnerability — it helped me generate a more thorough list of states to manually test than I might have thought of unprompted, and every one of those states still had to be tried, by hand, against the real application to see what actually happened.
What the Session Actually Held
Driftcode's password login, upon correct credential submission, set a pendingMfaUserId value in the server-side session, used by the subsequent MFA verification step to know which account to check the submitted code against. Separately, if I then abandoned that flow and initiated SSO login instead, completing authentication through the external identity provider, the application's post-SSO session-finalization logic checked for an existing, authenticated session to merge into — a reasonable-sounding feature intended to support account linking, letting a user who was already logged in link an SSO identity to their existing account.
The flaw was in what that finalization logic actually checked. Rather than verifying a fully authenticated session existed before attempting to merge, it checked only whether any user identifier was present anywhere in the session object — including, as I confirmed through direct testing, the pendingMfaUserId value left over from an incomplete, MFA-pending password login that had never actually been completed.
Building the Bypass
The sequence, confirmed step by step against my own test account:
- Start a password login with correct credentials, deliberately stopping right after the
pendingMfaUserIdvalue was set in session but before submitting any MFA code at all. - In the same browser session, navigate to the SSO login entry point and complete a full, legitimate SSO authentication using a separate identity provider account linked to a different test identity.
- Observe the finalization step: rather than creating a fresh session tied solely to the SSO identity, the application's merge logic found
pendingMfaUserIdalready present in session, treated it as evidence of an existing authenticated user, and completed a full, authenticated session for that account — the one whose password I knew but whose MFA step I had never actually completed — entirely bypassing the second factor that account's own login flow was supposed to require.
The resulting session was fully authenticated, with full access to the account associated with pendingMfaUserId, despite MFA never having been satisfied at any point in the sequence.
Why This Matters More Than "MFA Has an Edge Case"
It's worth being direct about severity here: this isn't a narrow edge case affecting some unusual configuration. Any account with MFA enabled, and credentials known to an attacker through any means — a leaked password, credential stuffing, phishing — becomes fully accessible without the second factor ever being satisfied, provided the attacker also has access to complete an SSO login for any identity at all, even one entirely unrelated to the target account, simply to trigger the vulnerable session-merge logic. Since Driftcode's SSO login was available to any user, including one registering a fresh identity through their own organization's identity provider for an entirely different Driftcode customer, this requirement was trivial to satisfy for essentially any attacker.
Scope
I confirmed this chain using two accounts I controlled entirely: a password-login test account whose MFA step I deliberately left incomplete, and a separate SSO-login test identity used purely to trigger the vulnerable merge logic. I never attempted this against any account whose password I hadn't set myself.
The Report
Title: Session puzzling vulnerability allows MFA bypass via SSO login finalization incorrectly treating a pending-MFA session marker as proof of authentication
Root cause: The SSO login finalization logic checks for the presence of any user identifier in the session object to determine whether to merge the new SSO identity into an existing authenticated session, without distinguishing between a genuinely authenticated session and one merely holding a pendingMfaUserId value left over from an incomplete, MFA-pending password login. This allows an attacker who knows a target account's password, but not its MFA code, to complete authentication for that account by instead completing an unrelated SSO login in the same session.
Reproduction: The full three-step sequence — incomplete password login leaving pendingMfaUserId set, a separate and genuinely legitimate SSO login in the same session, and the resulting fully-authenticated session for the MFA-incomplete account — demonstrated entirely using two self-controlled test identities.
Impact: Any attacker with a target account's password can achieve full authentication bypassing MFA entirely, provided they can complete any SSO login at all in the same session, a bar trivially met by registering their own unrelated identity through any supported identity provider.
Fix recommendations:
- Restrict the SSO merge logic to check specifically for a fully authenticated session state, never a partial or pending authentication marker like
pendingMfaUserId - Clear
pendingMfaUserIdand any other partial-authentication session data immediately upon starting a separate, unrelated login flow in the same session, rather than allowing stale intermediate state to persist across flows - Audit all session state fields set during any partial authentication step across every login flow for the same confusion risk, since this pattern generalizes beyond just the password-and-SSO combination tested here
What Happened After
Driftcode fixed the session-merge logic to require full authentication state within five days, and cleared partial-authentication session fields on flow transition as an additional safeguard. The report closed at $11,000, rated critical, reflecting a complete MFA bypass achievable against any account whose password was known by any means.
Why This Bug Class Rewards Mapping State, Not Just Testing Flows
Session puzzling bugs are nearly invisible to testing that treats each authentication flow as a closed, independent unit, because the vulnerability only exists in what happens when a user's session genuinely touches more than one flow, in an order the original developers of either flow individually never had reason to consider. Deliberately abandoning a flow partway through and switching to a different one, then inspecting what state carried over, is a specific and underused testing habit worth building — and it's exactly the kind of creative "what combinations should I actually try" enumeration where briefly brainstorming with an LLM can widen your test list, as long as every candidate still gets manually, carefully verified by hand against the real application rather than assumed.