Password-reset flooding abuses the request that starts recovery. The attacker does not need to reset a password successfully to create trouble: repeated requests can burden the delivery system and interrupt the account owner's use of their inbox.
Protect the request stage before it queues a message. Keep recovery usable for the person who actually owns the account, and review token redemption separately from message sending.
OWASP's forgot-password guidance recommends controls against excessive submissions and warns against changing or locking an account before a valid reset token is presented.
Follow the recovery timeline
For one synthetic account, identify the events from submission to completion:
- request received;
- request accepted or suppressed;
- delivery job queued;
- provider accepts or rejects the message;
- token presented;
- token accepted, expired, or already used;
- password changed and recovery completed.
Record an opaque correlation reference across those events. Keep the token and full recovery link out of ordinary logs.
A count of successful HTTP responses does not tell you how many messages were sent. Many applications intentionally return the same acknowledgment for requests that produce different internal actions. Monitor the internal stages without exposing their differences through the public response.
Separate request limits from delivery limits
A request budget controls how frequently clients reach the recovery endpoint. A destination or account budget controls how much delivery work targets one recipient. Both can matter when traffic changes source addresses.
Use a server-side resend policy. A disabled button is helpful interface feedback, but it cannot enforce a delivery allowance on direct requests. Explain when the user can try again without revealing whether an arbitrary account exists.
If the delivery provider is slow, avoid treating each frontend retry as a fresh need for another message. OWASP's business-logic guidance covers retry-safe external actions and explicit workflow state. Apply those principles to the actual semantics of your recovery service.
Investigate the failure at the right stage
| Symptom | First question |
|---|---|
| Requests rise, queued messages do not | Are controls suppressing excess work as intended? |
| Queued messages rise, deliveries stall | Is the provider or queue failing? |
| One recipient gets repeated messages | Is the destination allowance enforced server-side? |
| Users receive links that are already unusable | Are resend and invalidation rules conflicting? |
| Password changes occur without expected confirmation | Is token redemption or identity handling faulty? |
The final row is more serious than delivery flooding and requires its own investigation. Do not describe every reset anomaly as the same attack.
Make token and resend rules agree
Use unpredictable reset tokens, a bounded lifetime, and single-use redemption, as described in the OWASP recovery guidance. Then decide what happens when another reset is requested.
If every request invalidates the previous token, repeated requests could interfere with a legitimate recovery attempt. If several tokens remain valid, define the allowed overlap and invalidate appropriate outstanding state when recovery succeeds. Review that tradeoff with the identity owner.
Also check a slow user, a delayed email, a link opened on another device, and two browser tabs. Those are ordinary situations a recovery design must handle.
Respond without handing the attacker a lockout switch
For a suspected flood, preserve a small redacted timeline and narrow the controls to the affected request or delivery path. Monitor recovery completion, delivery backlog, and support complaints together.
Do not ask users to keep requesting more messages as a generic workaround. Give them a clear fallback and let support investigate using the correlation reference rather than forwarding a live reset link.
For unintended account disclosure, use account-enumeration prevention. For automated attacks across login and recovery, see the account takeover use case. Keep the recovery timeline with the change so the next on-call engineer can tell suppression, delivery failure, and token failure apart.
