Threat Modeling OTP Flows · Chapter 4 of 6
MFA fatigue and push bombing
When the second factor is a button, attackers press it for you until someone gives in. Model the attack and design approvals that resist it.
Push-based multi-factor authentication replaces typing a code with tapping Approve on a notification. It is popular because it is easy. It is also vulnerable in a way codes are not: the attacker can trigger the prompt whenever they like. With a valid password, an attacker can send a stream of approval requests — sometimes dozens in a few minutes, sometimes one every night at 2 a.m. — until the user approves one by mistake, out of annoyance, or because a follow-up phone call from “IT support” told them to.
The attack is called MFA fatigue or push bombing. It requires no infrastructure beyond the stolen password and a script. Its success depends on human behaviour under repetition, which is exactly the kind of thing threat models tend to underrate. This chapter puts it on Pinecrest’s register, where staff use push approvals to reach the clinical systems.
Anatomy of an attack
Attacker view
Why I like push targets
- I already have the password from a breach or phish.
- Each prompt costs me nothing.
- The prompt rarely says who is asking or from where.
- A friendly phone call makes the next approval feel legitimate.
Defender view
What the approval must carry
- Proof that the approver can see the login screen (number matching).
- Context: application, location, device, time.
- A hard limit on prompts per account per hour.
- An easy, prominent “I didn’t do this” that triggers response.
Design controls
Number matching shows a two-digit number on the login screen and asks the user to type or select it in the push prompt. A user who did not start the login cannot see the number, so blind approval becomes impossible. This defeats the pure-fatigue variant decisively. It does not defeat relay phishing, because a relay proxy displays the real login screen, number included, to the victim. That is why number matching is a fatigue control, not a phishing control, and the register must say so.
Rich context — the application name, the approximate location of the login and the client type — helps users notice when something is wrong, though attackers can choose infrastructure near the victim to blunt location cues. Rate limits on pushes per account are essential: after three denied or unanswered prompts within ten minutes, stop sending pushes and require a different factor. Report buttons turn the victim into a sensor: a denied prompt with “this wasn’t me” should lock the password, alert security and start an investigation.
- Number matching on every push, without exceptions for “trusted” networks.
- No more than three prompts per account per ten minutes; then require a different factor.
- “Deny and report” as a primary button, not hidden behind a menu.
- Automatic password reset requirement after a reported push.
- Helpdesk script that never asks a user to approve a prompt.
The helpdesk is part of the attack surface
Many real incidents combine push bombing with a call from someone posing as IT support. Pinecrest’s answer, written into the model, is a simple rule broadcast to all staff and printed on badge cards: IT will never ask you to approve a sign-in. The helpdesk follows a script that verifies callers through a callback to a number in the HR system, not one the caller provides. These are organisational controls, but they belong in the same register as technical ones because they defend the same asset.
On 2026-10-03, Pinecrest ran an internal exercise, illustrative example: twenty volunteer staff received a burst of five pushes, then a scripted call. Before the badge-card campaign, six approved. After it, one did — and that one reported the call immediately after realising. A small sample, invented for this course, but the lesson matches field experience: organisational controls move human behaviour more than notification copy does.
Where push still fits
Push approval with number matching, rate limits and good context is a reasonable factor for low and medium assurance actions, and much better than SMS codes against SIM swap. It is not phishing-resistant, so it does not satisfy the higher rungs of the ladder from series 2. Pinecrest’s plan is to keep push for routine access to scheduling systems and require security keys for administrators and for anyone with access to bulk patient records.
push_policy:
number_matching: required
max_prompts: { window: 10m, count: 3, then: require_factor: [totp, passkey] }
on_deny_report: [lock_password, page_security, notify_manager]
context_shown: [app, city, client, time]
remembered_device_auto_approve: false| Threat | Inherent | Mitigation | Residual |
|---|---|---|---|
| Push fatigue → blind approval | High | Number matching + 3-prompt limit | Low |
| Push + fake helpdesk call | High | Badge-card rule, callback script, report button | Medium |
| Relay phishing with number shown | Critical | Security keys for admins and bulk-record access | Medium |
Timing is part of the attack. Prompts sent late at night or early in the morning reach people who are tired, half asleep, or reaching for the phone to silence it. Some teams add an extra confirmation step for pushes that arrive outside the user's usual working hours, or simply refuse pushes and require a code or passkey for logins at unusual times. The friction is small, because honest late-night logins are rare for most staff, and it removes the attacker's favourite window.
Another useful signal is the password itself. Push bombing requires a valid password, so a burst of prompts proves the password is compromised even if every prompt is denied. Treat a run of denied pushes as a confirmed credential leak: force a password change, review recent sign-ins and check whether the same password appears on other accounts. Too many organisations log the denials, congratulate the user and leave the stolen password in place.
Review push logs weekly at first. Patterns such as repeated denials for one account, prompts from unfamiliar locations, or approvals seconds after a denial tell you whether the controls are working.
push.send(user.device, {title: "Approve sign-in?",actions: ["Approve", "Deny"],});
// bench check
0/3 correct · 0 answered
1. What does number matching defeat?
2. After three unanswered or denied pushes in ten minutes, the system should…
3. Why is the helpdesk script part of the threat model?