Safeguard
Application Security

Account Recovery Is the Weakest Authentication You Have

You require strong passwords and enforce MFA, then built a flow that lets someone with inbox access bypass all of it. Recovery exists to let in someone who cannot satisfy the normal requirements, so every control above it is capped by how well it is built.

Priya Raman
Staff Security Engineer
6 min read

You require strong passwords, enforce multi-factor authentication, and rotate sessions on privilege change. Then you built a flow that lets someone with access to an email inbox bypass all of it, and you tested it once, for whether it works.

Account recovery is the weakest authentication path in most products, because it exists precisely to let someone in who cannot satisfy the normal requirements. Every control above it is capped by how well it is built.

This post is what to get right across the recovery paths. For whoever owns authentication.

The reset token

Most of the classic failures are here.

Entropy and generation. A cryptographically secure random value, not a hash of the user id and a timestamp, not a sequential identifier, not a UUID from a non-cryptographic source. Anything predictable is a full account takeover, remotely, without touching the user.

Short expiry. Minutes to an hour. A link that works for a week sits in an inbox that may later be compromised, and it is exactly what an attacker looks for after gaining mailbox access.

Single use, invalidated on use. Obvious, and worth testing rather than assuming, because an implementation that marks it used after the password change can be raced.

Invalidated on other events. A successful login, a password change by another route, or a new reset request should invalidate outstanding tokens. Otherwise an old link in an old inbox remains live indefinitely.

Stored hashed. The token is a credential. A database read should not hand someone a working reset link for every user, and this is routinely missed because the token feels temporary.

Not leaked in transit. In the URL path or query string it lands in browser history, referrer headers on any outbound link from the reset page, and server access logs.

Do not reveal whether the account exists

The reset form is a user enumeration oracle if it says "no account with that email". Return the same response either way, send mail either way (to a non-existent address it goes nowhere), and take roughly the same time.

This applies equally to signup and to invitation flows, which frequently leak the same fact through a different door.

The email change flow is the real target

Reset gets attention. Email change usually does not, and it is more valuable to an attacker, because changing the address makes the takeover permanent and locks the owner out of recovery.

Four things it needs:

Re-authentication immediately before, not reliance on the existing session. A session obtained through a stolen laptop or a hijacked cookie should not be sufficient to change where recovery mail goes.

Verification of the new address before the change takes effect. Until they prove control of it, the old address remains the address of record.

Notification to the old address, always, with a way to reverse it. This is the control that catches an in-progress takeover, and it is the one most often omitted because it feels redundant.

A cooling-off period on recovery after an email change. If recovery to the new address works instantly, the change plus a reset is a complete takeover in two steps.

Multi-factor recovery is where MFA actually gets bypassed

You can implement MFA perfectly and give it away at the recovery desk.

Backup codes should be generated once, shown once, stored hashed, and single use. If they are retrievable later from account settings without re-authentication, they are not a second factor.

"I lost my device" self-service that disables MFA after an email confirmation reduces your two factors to one: the inbox. If you offer it, it needs a delay measured in days, with notification, so the legitimate owner can object.

The support path is the one attackers actually use. Whatever your documented identity verification is, it will be applied by someone under time pressure who wants to be helpful. Write down exactly what is sufficient, make it something an attacker cannot gather from public sources or a data breach, and require a second approver for MFA removal on high-value accounts.

Knowledge-based verification, last four digits, date of birth, recent transaction amounts, is weak against anyone who has done basic research. Treat it as a filter for honest mistakes, not as authentication.

What must happen after a successful reset

Three things, and the first is skipped surprisingly often:

Invalidate every existing session. Otherwise an attacker who was already in stays in, and the user believes they have locked them out.

Revoke API tokens and application passwords, or at minimum tell the user they exist and offer to revoke them. These survive a password change by design and they are how persistence is maintained.

Notify the user on a channel they still control, and say what changed and when.

Test the whole path

# Is the token predictable? Request several and compare.
# Is it single use? Use it twice; the second must fail.
# Does it survive a password change by another route? It must not.
# Does the reset form reveal account existence? Compare bodies and timings
#   for a real address and a random one.
# After reset, is an older session still valid? It must not be.
curl -s -o /dev/null -w "%{http_code}\n" -H "Cookie: session=$OLD_SESSION" \
  https://app.example.com/api/me
# want 401

That last one is the highest-yield test in the list and it takes a minute.

The concession

Every control here adds friction to a flow used by people who are already locked out and frustrated, and support cost is a real business cost. A cooling-off period on recovery after an email change will generate complaints from legitimate users who changed their address for ordinary reasons.

So calibrate by account value rather than applying the strictest version everywhere. A consumer account with no payment method and a business account with administrative access to a tenant do not need the same recovery friction. The mistake is picking one policy, and picking it for the lowest-value case.

The implication

Your authentication is exactly as strong as the easiest path to a valid session, and that path is almost never the login form.

Map every route to an authenticated session: login, reset, email change, MFA recovery, support intervention, invitation acceptance. The weakest one is your real authentication strength, and it is usually the one nobody has threat modelled.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.