Preventing MFA Fatigue and Push Bombing
Push-based second factors fail in a way that codes do not: an attacker holding a valid password can simply keep asking, and eventually somebody taps approve to make their phone stop buzzing. This page is part of the multi-factor authentication with TOTP and FIDO2 guide and covers the controls that close it.
The Attack Is a User-Experience Flaw
The mechanics are trivial. The attacker has the password — from a breach, a phishing page, or reuse — and triggers authentication repeatedly. Each attempt sends a prompt to the real user’s device. Some fraction of users, at some hour of the night, will approve one: because they assume it is a glitch, because they were logging in themselves at that moment, or simply to stop the notifications.
Number Matching Removes the Free Guess
The single most effective change is to stop the prompt being answerable without looking at the screen that started the login. Display a two- or three-digit number on the login page and require the user to select or type it on their device.
An attacker triggering a login from their own machine sees their own number, but the user’s device shows a choice — and the user has no way to know which to pick unless they are the one looking at the login screen. A reflexive tap is no longer possible, because there is nothing to tap.
Show context alongside the number: the application, the approximate location, the device and the time. Context does not stop a determined approval, but it converts “something is asking me to approve” into “something in another country is asking me to approve”, which is a question people answer correctly far more often.
Rate Limiting, Backoff and Lockout
Number matching removes the easy path; limits remove the attempt volume that makes fatigue possible in the first place.
Treat a denial as more than a failed attempt. A single explicit denial should raise the cost of the next attempt substantially; two or three should lock the factor, end any sessions for that account, and notify the user through a channel the attacker is unlikely to control. The password is presumed compromised at that point, so prompting for a reset is appropriate rather than alarmist.
Count attempts per account rather than per address. An attacker rotating through addresses defeats an address-based limit trivially, and the account is the thing being attacked.
The Structural Fix
Number matching and rate limits make the attack expensive. Moving to a phishing-resistant factor removes it, because there is no prompt to spam: a passkey or security key requires the user to be on the real login page with their authenticator, and an attacker with only a password has nothing to trigger.
That is the direction to travel, and the passkeys walkthrough covers the rollout. In the meantime, treat push approval as a factor that needs its own hardening rather than as an equivalent to a hardware key — and never let a push approval alone satisfy a step-up check for a high-value operation.
Keep the fallback ladder honest too. If push can be bypassed with an SMS code when the phone is unreachable, the account’s real strength is SMS, and every control above it is decoration.
Designing the Prompt Itself
The prompt is a security control with a user interface, and small wording choices change how often it is answered correctly.
Lead with the decision, not the brand. “Approve sign-in?” invites a reflex; “Someone is trying to sign in from Frankfurt on Windows — is this you?” invites a judgement. Put the number-matching challenge above the buttons so the user cannot act before reading, and make the deny action at least as prominent as approve, because the safe answer should never require more effort than the unsafe one.
Give denial a consequence the user can see. A prompt that says “if this was not you, deny and we will lock your account and help you reset your password” tells the user that denying is useful rather than merely dismissive. Users who believe denial does nothing tend to approve instead, on the theory that the notifications will otherwise continue.
Avoid prompting when you do not need to. Every unnecessary prompt trains users to approve without reading — which is exactly the reflex the attack exploits — so use device recognition and risk signals to keep routine sign-ins on a familiar device from generating one. The prompts that remain then carry information simply by existing.
Finally, make the prompt expire quickly. A challenge that stays actionable for ten minutes gives an attacker a long window in which the user might wander back to their phone and clear notifications carelessly; sixty to ninety seconds is enough for a legitimate login and short enough to make opportunistic approval unlikely.
Detecting the Attack in Progress
Push bombing is one of the most detectable attacks in authentication, because its signature is unusual by construction: many prompts for one account in a short period, from a source the account has never used, with denials or timeouts rather than approvals.
Alert on the pattern rather than on any single event. Count prompts per account per five minutes, and page when it exceeds a threshold no legitimate user reaches. Include the source address, the user agent and the geography, so the responder can tell immediately whether this is an attack or a user with a broken client retrying.
Watch for the quieter variant too: a low, steady rate of prompts spread over hours, designed to stay under a naive threshold. A per-account daily count catches that where a per-minute rate does not, and the two together cover both shapes.
Feed confirmed cases back into the password side. An account under push bombing has a compromised password by definition, so the response includes forcing a reset and checking whether that password appears in a known breach corpus — otherwise you have stopped this attempt and left the credential that enabled it in place for the next one.
Frequently Asked Questions
Is number matching enough on its own?
It removes the reflexive approval, which is most of the attack, but it does not stop an attacker who is on the phone to the user talking them through it — a technique that has worked repeatedly in real incidents. Pair it with rate limits, context in the prompt, and alerting on denials, and treat phishing-resistant factors as the destination rather than an optional upgrade.
How many prompts should an account be allowed?
Very few — three to five per account in a short window is generous, because a legitimate user rarely needs more than one or two. Apply increasing delays after each denial, and lock the factor after a small number of explicit denials. The cost of being slightly too strict is a support contact; the cost of being too permissive is an approved login the user did not intend.
What should happen when a user denies a prompt?
Treat it as a reported compromise, not a failed login. End other sessions for the account, block further prompts for a period, notify the user through a separate channel with details of the attempt, and prompt for a password change — because a denial means someone else had the password. Logging it and moving on wastes the clearest signal you will ever get.
Should we remove push approval entirely?
Eventually, in favour of phishing-resistant factors, but a sudden removal usually pushes users onto something weaker such as SMS. The workable path is to make passkeys the default, keep hardened push with number matching as a fallback, and remove push only when adoption makes it unnecessary — while never letting it satisfy the highest-assurance operations in the meantime.
Does this affect time-based codes as well?
Codes are not vulnerable to fatigue in the same way, because there is no prompt to spam — the user must actively read a code. They remain vulnerable to real-time relay through a phishing proxy, which number matching does not address either. Different attack, same conclusion: the durable fix is an origin-bound factor.
Treat every one of these controls as a stopgap on the way to origin-bound factors, and the roadmap writes itself.
Related
- Multi-factor authentication with TOTP and FIDO2 — factor strength and which one may satisfy which operation.
- Implementing passkeys and WebAuthn — the phishing-resistant factor that removes the attack.
- Enforcing step-up authentication for sensitive actions — why a push approval should not satisfy the highest tier.