Recommended
Tell people when their password worked but the second factor failed
When a sign-in passes the password but fails the second factor, offer another factor and notify the account owner. Show the attempt at their next sign-in too.
Applies when
The project has user accounts.
How to do it
A correct password followed by a failed factor means the person lost the factor or someone else knows the password. The OWASP Multifactor Authentication Cheat Sheet asks for three steps. Offer another bound factor or a recovery code. Offer a reset of the factor. Tell the owner, with the time, browser and approximate place. Send that notice as tell people about every change to their sign-in sends its notices. Add a link to change the password. Send one notice per sign-in attempt, not one per wrong code. Count the wrong codes as offer two-factor login says.
Examples
Using these examples: they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.
JavaScript example
export async function onSecondFactorAbandoned(attempt) {
if (!attempt.passwordOk || attempt.secondFactorOk || attempt.noticeSent) return;
await securityLog.append({ userId: attempt.userId, type: 'second_factor.failed', device: attempt.deviceLabel, place: attempt.place });
await mailer.sendSecurityNotice(attempt.userId, { type: 'second_factor.failed', at: attempt.startedAt, device: attempt.deviceLabel, place: attempt.place });
await attempts.markNoticeSent(attempt.id);
}
Python example
def on_second_factor_abandoned(attempt) -> None:
if not attempt.password_ok or attempt.second_factor_ok or attempt.notice_sent:
return
event = {"type": "second_factor.failed", "at": attempt.started_at, "device": attempt.device_label, "place": attempt.place}
security_log.append(user_id=attempt.user_id, **event)
mailer.send_security_notice(attempt.user_id, event)
attempts.mark_notice_sent(attempt.id)
How to check
On staging, enter a test user's correct password, then three wrong codes, then leave. One notice arrives with the time and browser. The next sign-in shows the failed attempt. The code page links to another factor and to a recovery code.
Sources
Related rules
- Tell people about every change to their sign-in in Accounts
- Offer two-factor login in Security testing
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/accounts/second-factors-and-recovery/failed-second-factor">Agent Wranglers accounts playbook</a>. In code you write, add a comment next to it with the same link.