Skip to main content

Command Palette

Search for a command to run...

An Unrequested 2FA Code Is a Log Line You Can Read

Updated
4 min readView as Markdown
A
I run AI Tools Primer (https://aitoolsprimer.com), an independent publication of tested guides to AI tools and everyday software. Three rules: every tool is tried before it is written about, prices are checked the month of publication, and nothing is claimed without a source. I also build the site itself — the navigation is a small three.js island where every building is a subject: https://aitoolsprimer.com/3d-island.html

If a verification code lands on your phone and you did not ask for it, you are reading a log line from somebody else's auth server. It says: at this timestamp, someone submitted this identifier to this service, and the service believed it enough to spend an SMS on it.

That is a surprisingly precise signal, and almost nobody treats it as one.

What the message actually proves

A code is minted at request time. It does not exist until a request is made. So an unrequested code is proof that a request happened — not proof that a password was correct, and not proof of compromise. Those are three different claims and the SMS only supports the first.

The Federal Trade Commission frames the two factors like this: "the password is the lock on the doorknob, the verification code is the deadbolt." An unrequested code is a report from the doorknob. Somebody is at the door. Whether the first lock already gave way is exactly what the message does not tell you.

The boring explanation is often the right one

People mistype their own phone numbers constantly, and services accept them. Stripe says so plainly in its own support material about Link: "If you did not save your payment information to Link or Stripe, someone may have entered your phone number by mistake."

So the interesting question is not what the message says. Reading the wording more carefully will not help you, because a legitimate code and an attacker-triggered code are generated by the same template in the same system. They are byte-identical.

The signal is frequency.

  • One code, once, on a service you use, never repeating: almost certainly a stranger one digit away from you.
  • Three in ten minutes: someone is retrying.
  • Codes from services you never registered with: your identifier is being run down a list.
  • A code that arrives minutes after a phone call from "support": you are the target, and the call is the other half of the attack.

That last one is the one that works in practice. The attacker already has the password from a breach. They trigger the code, then call before it expires and ask you to read it back "to confirm your identity". They are not stealing the code. They are asking for it, politely, and that is where most successful takeovers actually happen.

If you ship the login flow, you own part of this

Three things that cost almost nothing and change what the recipient can infer:

Name the action, not just the code. "Code to sign in on a new device" and "code to change your recovery email" are different emergencies. A bare six digits makes the user guess.

Include whatever context you already have. Approximate location, browser, platform. You are logging it anyway. The user cannot evaluate an attempt they cannot see.

Give a real "I did not request this". Not a support link — an action that invalidates the pending attempt and flags the account. If the only thing a user can do with a suspicious code is ignore it, you have built an alarm with no off switch, and people stop hearing alarms they cannot act on.

And the rule your support team should never break, because it is the one thing that makes the user-side rule teachable: never ask a user to read a code back. Not once, not for identity confirmation, not as a fallback. The moment one legitimate company does it, "no legitimate company will ever ask" stops being true, and every user who learned that rule loses it.


I wrote up the non-developer version of this — what to do, in order, when a code you did not ask for shows up — at aitoolsprimer.com.