CybersecurityJune 1, 202610 min read

MFA Fatigue and Session Hijacking: The Attacks That Beat 2FA

Attackers stopped cracking passwords and started stealing sessions. Here is how MFA fatigue and token theft work, and how to shut them down.

By Innovation T Team


You turned on 2FA and told the board you were covered. You were not. Attackers stopped fighting your login and started skipping it. The password still matters, but the two techniques winning right now, MFA fatigue and session hijacking, treat your second factor as a speed bump, not a wall.

Why 2FA stopped being enough

Classic phishing steals a password. MFA was the answer: even with the password, the attacker lacks the second factor. That logic held until attackers changed targets.

Two shifts broke the model:

  • The human got tired. Push-based MFA asks a person to approve. People approve things all day. Attackers learned to weaponize the reflex.
  • The session became the prize. Once you authenticate, the server hands your browser a session token. That token, not your password, is what proves you are you on every request after login. Steal the token and you skip the password, the MFA prompt, everything.

Both attacks share one root cause: authentication is an event, but access is a state. We spend heavily on the event and almost nothing on the state that lives for hours or days afterward. If you want the deeper version of this argument, read our take on zero trust architecture. The short version: never trust a session just because a login once succeeded.

MFA fatigue, also called push bombing

The mechanics are dumb and effective. The attacker already has the password (from a breach dump, a phishing kit, or an infostealer). They log in. Your phone lights up with an approval prompt. They log in again. And again. Ten prompts. Fifty prompts. At 2 a.m.

Eventually one of three things happens:

  1. The user taps approve to make the noise stop.
  2. The user assumes IT is doing maintenance and approves.
  3. The attacker calls, posing as help desk, and talks the user through it.

That is the whole attack. No zero-day, no malware. It works because a plain "Approve / Deny" push carries no context and costs the user nothing to accept.

Fixes that actually change the odds

  • Number matching. The login screen shows a two-digit number the user must type into the app. An attacker who cannot see the login screen cannot supply the number. This alone kills the blind-approval path.
  • Context in the prompt. Show location, application, and IP. "Sign-in from Lagos to your payroll app" is a lot harder to fat-finger than a blank approve button.
  • Rate limiting and lockout on repeated pushes. Three denied or ignored prompts in a short window should freeze new prompts and alert your SOC. Push bombing is loud by nature. Detect the volume.
  • Move off push entirely for high-value accounts. Number matching is a patch. Phishing-resistant factors are a cure (more below).

Number matching is now the default in most identity platforms. Turn it on. If your provider still allows simple approve/deny for privileged users, that is a finding, not a preference.

Session hijacking: stealing the token, skipping the login

This is the more dangerous family because it defeats good MFA too. Even a perfect number-matched login ends by issuing a session token. If the attacker gets that token, your MFA never gets a vote.

There are three common paths to the token.

1. Adversary-in-the-middle (AiTM) phishing

This is the technique behind most modern MFA bypass. The attacker runs a reverse proxy (Evilginx and similar kits made this point-and-click) between the victim and the real site.

The flow:

  1. Victim clicks a phishing link and lands on the attacker proxy, which looks pixel-perfect because it is literally relaying the real site.
  2. Victim types the password. Proxy forwards it to the real site.
  3. Real site sends the MFA prompt. Victim completes it. Number matching, TOTP, SMS: all satisfied, because a real human is really logging in.
  4. The real site issues a valid session cookie. The proxy captures it in transit.
  5. Attacker imports the cookie into their own browser and is now inside, fully authenticated, MFA already satisfied.

The victim did everything right and still lost. That is why "we have MFA" is not an answer to "are we phishing-resistant."

2. Infostealer malware and cookie theft

You do not need a proxy if you can read the victim's disk. Infostealers (RedLine, Lumma, and the rest of the market) grab browser cookie stores, saved tokens, and local session files, then sell them on. The buyer loads your live session and walks in. No password prompt, no MFA, because the token is already minted.

This is why an endpoint compromise is an identity compromise. The two are not separate incidents.

3. Token theft in OAuth and API flows

Long-lived refresh tokens and misconfigured OAuth apps are a quiet goldmine. A stolen refresh token can mint new access tokens for weeks. Overscoped tokens turn one leak into tenant-wide access. If your platform issues tokens to third-party integrations, each one is a credential you may not be rotating. We go deep on scoping and rotation in API security best practices.

The defense that actually holds: phishing-resistant MFA

Here is the uncomfortable truth. Number matching helps against fatigue. It does nothing against AiTM, because the human still hands a real credential to a real site through a proxy. To beat AiTM you need a factor that is bound to the origin and cannot be relayed.

That factor is FIDO2 / WebAuthn, delivered as passkeys or hardware security keys.

Why it resists AiTM: the authenticator signs a challenge that includes the origin (the real domain). A proxy on a look-alike domain produces the wrong origin, so the signature does not validate. There is no code to phish, no cookie the human can be tricked into forwarding. The cryptography refuses to work off the legitimate domain.

If you read one companion piece, make it passkeys and passwordless authentication. For admins, finance, and anyone with production access, phishing-resistant MFA should be mandatory, not optional.

Priority order for MFA strength:
  1. FIDO2 / passkeys / hardware keys   (phishing-resistant, beats AiTM)
  2. Number-matched push + context      (beats fatigue, not AiTM)
  3. TOTP authenticator apps            (phishable via proxy)
  4. SMS / voice OTP                     (phishable + SIM-swap risk)

Do not deploy the top tier only. Deploy it first for the accounts that would end your quarter if compromised.

Protecting the session itself

Phishing-resistant MFA protects the login. You still have to protect the token after it is issued, because malware and misconfig can grab it directly.

Bind the token to the device

The strongest control is token binding: cryptographically tie the session to the device that authenticated, so a stolen cookie is useless on another machine. Two mechanisms to know:

  • DPoP (Demonstrating Proof of Possession) for OAuth. The client proves it holds a private key on every request. A copied token without the key is dead on arrival.
POST /api/orders HTTP/1.1
Authorization: DPoP eyJ...access_token...
DPoP: eyJ...signed_proof_bound_to_request_and_key...
  • Device-bound sessions in the browser layer. Emerging standards (often marketed as device bound session credentials) refresh cookies using a device-held key, so an exfiltrated cookie expires quickly and cannot be reused elsewhere.

Harden cookies the boring way

Most session theft exploits sloppy cookie handling. The defaults matter:

Set-Cookie: session=...;
  HttpOnly;          // JavaScript cannot read it, blunts XSS theft
  Secure;            // never sent over plain HTTP
  SameSite=Lax;      // limits cross-site sending, cuts CSRF
  Path=/;
  Max-Age=3600       // short life, small blast radius

HttpOnly alone stops a large class of cookie exfiltration through cross-site scripting. If your session cookie is readable from JavaScript, fix that before anything else on this page.

Shorten what a stolen token can do

  • Short access-token lifetimes. Minutes, not hours. Force frequent re-validation.
  • Refresh-token rotation with reuse detection. Each refresh issues a new token and invalidates the old one. If an old token reappears, that is theft: kill the whole session family.
  • Bound token scope. Least privilege per token. A leaked read-only token is an incident. A leaked god-mode token is a breach.

Detect the hijack you could not prevent

Assume one token gets out. Your job is to make its life short and noisy.

  • Continuous Access Evaluation (CAE). Instead of trusting a token until it expires, re-check conditions in near real time. Password reset, disabled account, risky location: revoke mid-session, not next hour.
  • Impossible travel and device anomalies. A session in Sousse at 14:00 and Manila at 14:10 is not a commuter. Flag it, step up, or kill it.
  • User agent and IP drift within a session. A token that jumps from a corporate laptop fingerprint to a random cloud VM is stolen. Alert on the shift.
  • Log the session lifecycle, not just logins. Token issuance, refresh, and revocation belong in your telemetry. You cannot investigate what you never recorded. Pair this with the wider view in observability: logs, metrics, and traces.

When an alert fires, you need a rehearsed response: revoke sessions, rotate tokens, and force phishing-resistant re-enrollment. Have that written down before you need it. Our incident response playbook covers the token-revocation steps most teams forget until 3 a.m.

A decision framework you can apply this quarter

You cannot do everything at once. Prioritize by blast radius.

  1. Inventory privileged access. Admins, finance, production, and anyone who can move money or data. This is your tier one.
  2. Mandate phishing-resistant MFA for tier one. Passkeys or hardware keys. No exceptions, no TOTP fallback for these accounts.
  3. Turn on number matching and prompt context everywhere else. This is your fatigue patch for the broad population.
  4. Set cookie and token hygiene as policy. HttpOnly, Secure, SameSite, short lifetimes, refresh rotation with reuse detection. Verify in code review, not in a wiki.
  5. Enable CAE and session anomaly detection. Stop trusting tokens for their full lifetime.
  6. Rehearse revocation. Run a tabletop where a token is stolen. Time how long it takes you to kill every session. If you do not know the number, that is the finding.

The pattern: prevent what you can with cryptography, contain what you cannot with short-lived, bound, revocable sessions.

Quick self-audit checklist

  • Privileged accounts use FIDO2 / passkeys, not push or TOTP.
  • Number matching and sign-in context are on for all users.
  • Session cookies are HttpOnly, Secure, and SameSite.
  • Access tokens expire in minutes; refresh tokens rotate.
  • Refresh-token reuse triggers full session revocation.
  • Token binding (DPoP or device-bound sessions) is in place for sensitive APIs.
  • CAE or equivalent revokes sessions on risk events mid-session.
  • Session issuance, refresh, and revocation are logged and alertable.
  • You have timed a live session-revocation drill in the last 90 days.

If you want to know how these controls hold up against a real operator, that is what a proper engagement tests. See penetration testing 101 for how an AiTM and token-theft scenario is exercised end to end.

How Innovation T can help

We build and harden the authentication layer teams actually ship: passkey rollouts, phishing-resistant MFA for privileged access, token binding, refresh-token rotation, and session anomaly detection wired into your logging. Not slideware. Working controls, tested against the exact attacks above.

If your 2FA is one convincing proxy away from a full session takeover, let us pressure-test it and close the gap. See our services or contact the team and we will map your fastest path from "we have MFA" to "we are phishing-resistant."

#MFA fatigue#session hijacking#token theft#security

Ready to build with Innovation T?

Whether it is security, growth or engineering, our team can help you ship it well.