“We have MFA” used to end the conversation. It doesn’t anymore. Most identity compromises we see today don’t defeat multi-factor authentication at all — they route around it, by stealing what MFA produces once it has already succeeded: a valid, authenticated session.
The mechanism is called adversary-in-the-middle phishing, and it’s not new, but it’s now the default toolkit rather than an advanced technique. A phishing kit sits transparently between the target and the real login page — Microsoft 365, Okta, Google Workspace, whatever the organisation actually uses. The victim types their real password into what looks like the real page, because it is a proxy of the real page. They get the real MFA prompt, because the kit is relaying it live. They approve it, because everything about the flow looks legitimate. The kit isn’t trying to guess a code or bypass a factor — it’s sitting in the room while the legitimate authentication happens, and walking out with the session cookie that authentication produces.
That cookie is the whole game. With it, an attacker can replay the session from their own machine, in their own country, with no further prompts — no password, no MFA challenge, because as far as the identity provider is concerned, this is simply the same already-authenticated session continuing. Push notifications, SMS codes, and time-based one-time codes are all defeated the same way, because none of them are actually being attacked. They all did their job. The session that came out the other end is just as valid as if the real user were still sitting at the keyboard.
There’s a second, older route to the same outcome: MFA fatigue. Push-based approval is convenient, which is exactly its weakness. An attacker with a stolen password triggers approval requests repeatedly, sometimes at odd hours, until a tired or distracted user taps approve just to make the notifications stop. No cookie theft required — the user hands over the session willingly, without meaning to. Both routes end in the same place: a defender looking at a login event that passed every check the identity provider knows how to run.
What actually holds up against this, in the order we’d prioritise it:
- Phishing-resistant MFA — FIDO2 and passkeys bind the credential to the specific origin being authenticated to. A proxy site simply cannot relay the challenge, because the cryptographic handshake checks the domain itself. This is the one control on this list that closes the AiTM route structurally rather than procedurally.
- Number-matching instead of one-tap approval — if push MFA is what you have, forcing the user to type a number shown on the login screen into the prompt removes the “just tap approve” reflex that fatigue attacks depend on.
- Conditional access on signal, not just identity — device compliance, impossible-travel checks, and IP reputation should all be factored into whether a session is trusted, so a token replayed from an unmanaged device on the other side of the world gets challenged again even though the token itself looks valid.
- Short token lifetimes and sign-in monitoring — a stolen session that expires in an hour, or that triggers an alert the moment it’s used from a second location, buys back most of the time an attacker was counting on.
“We have MFA” is the start of the conversation, not the end of it. The question worth asking isn’t whether MFA is enabled — almost everyone’s is, by now. It’s whether the session that MFA produces is being watched, bound, and trusted only as far as the evidence actually supports. That’s an identity-first testing question, not a checkbox, and it’s exactly where most conditional-access configurations we review still have gaps nobody’s walked through end to end.
