It is a quarter past midnight and a phone lights up with a login approval request. The user did not try to sign in. It lights up again a minute later, and again. After a dozen prompts, one of three things happens: the user taps Approve to make it stop, taps it by accident half asleep, or receives a message from someone claiming to be IT support who says the prompts are a known glitch and to approve one. The attacker already had the password, from a breach, a phishing page or a reuse of an old credential. The second factor was the only thing in the way, and it was defeated by annoyance. This is MFA fatigue, also called push bombing or prompt bombing, and it is a good illustration of why “we have MFA” is not a security posture by itself.

Why Second Factors Differ

MFA is not one control. Factors vary enormously in how well they resist attack:

FactorPhishable in real timeVulnerable to prompt bombingOther weaknesses
SMS codeYesPartially (code requests)SIM swap, number porting fraud, interception
Email codeYesPartiallyDepends on mailbox security
TOTP app codeYesNoCode can be relayed to a fake page
Simple push approvalYesYesApprove-to-dismiss behavior
Push with number matchingHarderLargely mitigatedSocial engineering still possible
FIDO2 / WebAuthn key or passkeyNoNoAccount recovery path, device loss

The pattern is clear. Anything the user can be talked into handing over or approving can be abused. Factors that are cryptographically bound to the legitimate site cannot be relayed to an imposter.

How the Attack Works

MFA fatigue is a second-stage attack. The attacker needs a valid first factor, so the preconditions are ordinary:

  1. Obtain credentials. Credential stuffing with passwords reused from other breaches, infostealer logs, or phishing.
  2. Trigger the prompt. Each login attempt with the correct password makes the identity provider send a push notification to the user’s enrolled device.
  3. Apply pressure. Many attempts in a row, often timed outside working hours so the user is tired or alone.
  4. Add social engineering. The attacker contacts the user by chat, email or phone, posing as the help desk or security team, and says the prompts need to be approved to stop them or to complete a “verification”.
  5. Use the session. Once approved, the attacker registers their own MFA device so they keep access even after the password is changed, then moves on to mail, VPN, cloud consoles or internal tools.

A related variant is real-time phishing proxies: a fake login page relays the user’s password and one-time code to the real site as they type, then captures the resulting session cookie. TOTP and SMS do not stop this. Because it defeats most OTP-style factors, the underlying defense is the same: use factors bound to the genuine origin. For the human side of these campaigns, see social engineering and phishing detection.

A third path is the help desk and recovery process. If an attacker can talk support into resetting MFA, they never need to fatigue anyone. Recovery is part of your authentication system and is attacked accordingly.

Defenses That Actually Work

1. Move to phishing-resistant factors

FIDO2/WebAuthn security keys and passkeys sign a challenge that includes the site’s origin. A lookalike domain gets nothing useful, and there is no prompt to approve or code to read out. For privileged accounts first, then everyone, make this the target state. See passkeys vs passwords for how the mechanism works and the rollout pitfalls.

Do not stop at enrollment. If a weaker method remains available as a fallback, an attacker will simply select the fallback. A policy that says “security key required” must actually remove SMS and push from the options for those accounts.

2. Enable number matching and context in push prompts

If push remains in use, require number matching: the login screen shows a two-digit number and the user must type it into the authenticator. An unsolicited prompt gives the user no number to enter, so a blind tap does nothing.

Also show context in the prompt: the application name, the approximate location and the device or browser. A request for “VPN, from a country you have never been to” is easier to refuse than a bare “Approve sign-in?” button.

Disable plain “Approve/Deny” prompts where the platform allows it.

3. Rate-limit and lock prompts

Prompt volume is a signal and a lever. Limit how many pushes a single account can receive in a time window, and after several denials or timeouts, suspend push for that account until the user or an administrator re-verifies out of band.

A sketch of the logic in an authentication service:

from datetime import datetime, timedelta

MAX_PROMPTS = 3
WINDOW = timedelta(minutes=15)
LOCK = timedelta(minutes=30)

def can_send_push(user, now: datetime) -> bool:
    if user.push_locked_until and user.push_locked_until > now:
        return False
    recent = [t for t in user.push_attempts if now - t < WINDOW]
    if len(recent) >= MAX_PROMPTS:
        user.push_locked_until = now + LOCK
        alert_security(user, reason="push_rate_exceeded")
        return False
    return True

Counting and locking at the account level matters, because attackers rotate source addresses to evade IP-based throttling.

4. Treat a denied prompt as an incident signal

A user who denies a prompt they did not initiate has just told you their password is compromised. Make that actionable:

  • Offer a “This was not me” button that reports the event and, ideally, forces a password reset and session revocation.
  • Notify the security team automatically after repeated denials.
  • Educate users that an unexpected prompt means the password is known to someone, not that the system is glitching.

5. Reduce password exposure

Fatigue attacks depend on a working password. Block known-breached passwords at set and change time, require uniqueness through a password manager, and monitor for credential-stuffing patterns. The less the first factor is worth, the less the second is tested.

6. Harden registration and recovery

An attacker who is approved once will try to enroll a new device. Defend that step:

  • Require recent strong authentication to add, remove or change an MFA method.
  • Send notifications to existing devices and to the user’s email when a method changes.
  • Apply a short cooling-off period or additional verification for newly enrolled factors on privileged accounts.
  • Give help desk staff a documented identity-verification procedure that does not rely on information an attacker can find (job title, birthday, manager name). Use a callback to a number on file, an in-person check, or approval from the user’s manager through a separate channel.
  • Log and review every MFA reset, and require a second staff member for resets on privileged accounts.

7. Use conditional access

Conditions let you refuse sign-ins the real user would not make:

  • Require compliant or managed devices for sensitive applications.
  • Block or step up on impossible travel and unfamiliar locations.
  • Deny legacy authentication protocols that bypass MFA entirely, such as basic-auth IMAP or SMTP.
  • Bind sessions to the device where practical.

Legacy protocols are a frequent gap: a perfectly configured MFA policy is irrelevant if an old protocol endpoint accepts a password alone.

Detection: What to Look For

Your identity provider’s logs already contain the evidence. Useful detections:

  • Multiple failed or denied MFA challenges for one user in a short window.
  • A successful MFA approval immediately after a run of denials or timeouts.
  • Sign-in from a new device, country or hosting provider followed by MFA method registration.
  • MFA approvals at unusual hours for that user.
  • Password success with MFA failure, repeated across many accounts from the same infrastructure, indicating credential stuffing at scale.
  • New mailbox rules, OAuth app grants or forwarding addresses created soon after a new sign-in.

An example of an SQL-style detection over exported authentication logs:

-- Users with 5 or more MFA denials or timeouts in 10 minutes,
-- followed by a successful approval
WITH bursts AS (
  SELECT user_id,
         MIN(event_time) AS first_seen,
         MAX(event_time) AS last_seen,
         COUNT(*) AS prompts
  FROM auth_events
  WHERE mfa_result IN ('denied', 'timeout')
  GROUP BY user_id, DATE_TRUNC('minute', event_time) / 10
  HAVING COUNT(*) >= 5
)
SELECT b.user_id, b.prompts, s.event_time AS approved_at, s.source_ip
FROM bursts b
JOIN auth_events s
  ON s.user_id = b.user_id
 AND s.mfa_result = 'approved'
 AND s.event_time BETWEEN b.last_seen AND b.last_seen + INTERVAL '30 minutes';

Tune thresholds to your environment. The exact grouping expression will vary by database; the logic is what matters: a burst of refusals followed by an approval deserves a human look.

Route these alerts to the same on-call path as other identity incidents, and have a ready response (see incident response playbook for structuring one).

Responding When It Happens

If a user reports unexpected prompts, or a burst followed by an approval appears in the logs:

  1. Contact the user through a known-good channel, not by replying to whatever message prompted the approval.
  2. Revoke all active sessions and refresh tokens for the account.
  3. Reset the password and review the registered MFA methods; remove any the user does not recognize.
  4. Review activity since the approval: mail rules, forwarding, OAuth grants, file downloads, new API keys or cloud credentials.
  5. Check whether the same password was used elsewhere and whether other accounts show the same pattern.
  6. Feed the finding back: which control would have stopped it, and is it deployed everywhere?

Testing Your Own Resilience

Run these only within your organization and with the approval of the people responsible for identity and security. A controlled exercise might verify that:

  • Number matching is enforced for every user group and application, with no plain-approve fallback.
  • A burst of failed prompts triggers throttling and an alert, and the alert reaches a human.
  • Legacy protocols are actually blocked, by attempting a password-only sign-in with a test account.
  • The help desk procedure holds up against an internal, announced social-engineering exercise.
  • Newly added MFA methods on a test privileged account generate notifications.

Measure the outcome in terms of detection and response time, not user blame. Users who fall for a well-built pretext are evidence of a process gap.

Trade-offs and Common Mistakes

  • Relying on user vigilance alone. Training helps, but design the system so a single tired tap is not enough.
  • Leaving SMS as a fallback. Fallbacks define your real security level.
  • Number matching without context is better than nothing but still leaves room for pretexting; keep rate limits and alerts.
  • Hardware keys without a recovery plan lead to lockouts and then to risky manual resets. Issue two keys per person and define a secure recovery path.
  • Exempting executives or service desk staff from strict policy. They are high-value targets.
  • Ignoring denied prompts. The denial is the earliest warning you will get.

Key Takeaways

  • MFA fatigue works because the attacker already has the password and relies on the user approving a push to make it stop, or on a convincing “IT support” pretext.
  • Factors differ widely: FIDO2 keys and passkeys resist both prompt bombing and real-time phishing, while SMS, TOTP and plain push do not.
  • If push stays, enforce number matching, show application and location context, and rate-limit prompts per account with a lockout and alert.
  • Treat a denied unexpected prompt as a compromised password: reset, revoke sessions and investigate.
  • Protect enrollment and recovery with recent strong authentication, notifications and a verified help desk procedure, since attackers will target them next.
  • Block legacy protocols, use conditional access and monitor logs for denial bursts followed by an approval and for new MFA registrations.