The one time code is a delivery receipt, not a decision.
SIM swap losses reported to the FBI fell to roughly $17 million in 2025, and that decline is real progress worth acknowledging. It is also the least interesting fact about the problem, because the codes that survived the cleanup are still guarding the endpoints where a single mistake is unrecoverable.
The first sign is almost always silence.
Picture someone sitting in an airport lounge at half past four in the afternoon, waiting on a delayed flight. Their phone has been quiet for a while, which at first is a relief. Then they notice the signal indicator has changed to a message about no service, and they do what everyone does: toggle airplane mode on and off, then restart the handset. Nothing. They connect to the lounge wifi instead, and messages start arriving over the internet, so the phone is clearly working. It is the cellular part that has stopped.
What has actually happened is that thirty five minutes earlier, in a retail store several states away, a person walked up to a counter, said they had upgraded to a new handset and needed their number moved to a new SIM, and answered a couple of questions well enough. The employee performed a routine, entirely legitimate operation that the carrier's systems are designed to allow, because people genuinely do lose phones and buy new ones every day. The number moved. From that moment, every message sent to that number arrived on a device in a stranger's pocket.
By the time the traveller is in a queue at a carrier store the following morning, the sequence is finished. A password reset link went to their email, and the email account used SMS as a backup. The exchange account they had not opened in months used SMS to confirm a new withdrawal address. The brokerage sent a code to authorise a linked bank account. None of these systems malfunctioned. Every one of them did exactly what it was built to do, which was to send a code to a number and accept that code back as evidence.
This post is about what that code actually proves, which is much less than the industry has spent fifteen years assuming, and about why the correct fix is not a better delivery channel.
Short answer: A one time code proves that whoever holds the phone number received a message. It does not prove who they are, and it does not prove what they intended. Because a carrier can reassign a number through a retail process, and because phishing kits relay codes in real time, SMS should not authorise consequential actions. Bind the approval to the action instead, with a signature from an enrolled device.
What actually happens during a SIM swap?
The mechanics are worth walking through slowly, because most descriptions skip the step that matters and the missing step is the whole lesson.
Step one: the attacker collects the boring information
Before anyone approaches a counter, the attacker assembles a small file on the target: full name, address, date of birth, the last four digits of a payment card, perhaps the account PIN if it has ever appeared in a breach corpus. None of this is exotic. Most of it has been available in aggregate for years, and the rest can often be obtained by calling the target and pretending to be their bank, their carrier, or a delivery company. The attacker is not breaking cryptography. They are assembling the answers to the questions a store employee is trained to ask.
Step two: the reassignment
The attacker then triggers a port or a SIM change. This can happen at a retail counter, through a call centre, through a carrier's own online self service, or, in the worst cases, through an insider who has been recruited or bribed. The critical property is that the operation itself is a supported feature. Nobody is exploiting a bug. A phone number is not a cryptographic key, it is a routing entry in a database, and the carrier owns that database and reassigns entries all day long as a matter of ordinary business.
This is the step that most write ups compress into a clause, and it deserves a full paragraph because it explains why the problem has been so stubborn. The security of every account that relies on SMS is delegated, silently and without any contract, to the weakest customer service interaction in a retail network with high staff turnover, sales targets, and thousands of locations. Nobody at any of those accounts chose that arrangement. They chose a text message.
Step three: the cascade
Once the number moves, the attacker does not attack the valuable account directly. They attack its recovery path. Email first, because email is the root of most identity graphs and because email providers accept SMS as a recovery factor. From email, they walk outward to anything whose reset link lands in that inbox. This is why the losses cluster at exchanges, brokerages, and executive accounts: not because those services are careless, but because they sit downstream of an email account that sits downstream of a phone number that sits downstream of a retail counter.
The cascade is the reason a single swap can be catastrophic while the individual controls all look reasonable in isolation. Each service checked something. The something they checked was the same something.
Are SIM swap losses actually going down?
Yes, and this deserves to be said plainly and without the usual caveats attached immediately, because security writing has a bad habit of refusing to acknowledge progress.
The FBI's Internet Crime Complaint Center reported SIM swap losses of roughly $17.4 million across 971 complaints in 2025, down from about $26 million the previous year, against a peak above $70 million in 2022 (FBI IC3 annual reports). That is a decline of more than three quarters from the peak in three years. Very few categories of cyber enabled fraud have moved in that direction over that period, and most have moved sharply the other way.
The decline has identifiable causes, and they are the unglamorous kind that actually work. In 2023 the Federal Communications Commission adopted rules addressing SIM swap and port out fraud, requiring carriers to adopt secure authentication procedures before transferring a number and to notify customers of change requests, with compliance arriving over the following period. Carriers rolled out port freezes and number transfer PINs. Several large platforms removed SMS as a login factor entirely or demoted it behind stronger options. Litigation against carriers raised the cost of sloppy retail procedure.
So the carrier layer improved, and the improvement is measurable. Anyone arguing that nothing has been done is not reading the numbers.
Why the falling number is not the whole story
Here is where the interesting analysis starts. A complaint count and a loss total are two different measurements, and they can move in opposite directions in ways that matter enormously for how you set policy.
Complaint counts fell roughly in line with losses, which suggests genuine suppression rather than a shift in reporting. But a category can shrink in volume while the surviving incidents become more severe, because the defenders who fixed the problem are typically the ones with the most to lose and the most resources, and the attackers who remain are the ones willing to invest in a smaller number of high value targets. A retail scale attack on a thousand ordinary accounts is a business that carrier controls can disrupt. A patient, well researched attack on one account with a large balance is not the same business, and it responds to different economics.
The evidence for this is not in the aggregate statistics, which is exactly the difficulty. It is in the shape of the individual incidents that still occur, and in a structural fact that anyone can verify for themselves: SMS has largely been removed as a primary login factor at serious institutions, and has very much not been removed as a recovery channel or as a confirmation channel for high value operations. The strong front door now sits in a frame with a weak side panel.
That is the honest version of the argument, and it is narrower than the usual scare framing. The claim is not that SIM swapping is an epidemic. The claim is that it is a low frequency, high severity risk concentrated at precisely the endpoints where recovery is impossible, and that low frequency high severity risks are the ones organisations systematically under invest in, because they do not show up often enough in the incident review to earn a budget line.
What does a one time code actually prove?
Strip away the branding and a one time passcode is a very simple assertion. The system generated a secret, sent it through a channel, and later received the same secret back. From this it concludes that the party who returned the secret is the party the channel belongs to.
Think about what a courier does when they deliver a parcel and ask for a signature. The signature on the handheld device establishes that somebody at that address received the parcel. It does not establish that the person who signed is the person who ordered it, that they wanted it, or that they agreed to anything by accepting it. It is a delivery receipt. It answers the question "did this arrive" and no other question at all.
A one time code is the same instrument. It is a receipt for delivery to a channel. It answers "did this arrive at the number on file" and nothing else. Everything the industry has built on top of it, the idea that entering the code proves identity, proves consent, proves that the account holder wanted a particular transfer to a particular destination, is an inference layered onto an assertion that never carried that much weight.
The inference held up reasonably well when two conditions were true: phone numbers were hard to reassign, and codes were hard to relay. Neither condition is true now. Numbers are reassigned by design through a retail process, and codes are relayed in real time by phishing infrastructure that any competent attacker can rent, which is the subject of our piece on adversary in the middle session theft.
The standards bodies said this a long time ago
It is worth noting that none of this is a new discovery. The National Institute of Standards and Technology has for years treated SMS as a restricted authenticator in its digital identity guidance, meaning that its use is discouraged and that a service choosing to use it is expected to assess the risk and offer alternatives. The guidance is explicit about the underlying reason, which is that the channel is not bound to a device and can be redirected by the carrier or intercepted in transit.
The guidance has been in place long enough that its persistence in deployment is not an information problem. Everyone building these systems has known for years. The reason SMS survives is that it works for the enormous population of users who have a phone and nothing else, and no organisation wants to be the one that locks those users out. That is a legitimate concern and we will come back to it, because any recommendation that ignores it is not a real recommendation.
Does an authenticator app fix it?
Partly, and the part it fixes is the part in the headline.
A time based one time password generated by an app on your phone is not routed through the carrier, so reassigning your number does nothing to it. Against the SIM swap specifically, moving from SMS to an authenticator app is a genuine improvement and anyone who has not done it should. That is the honest good news and it should not be buried.
But now apply the courier test again. The app generates a six digit number. You type that number into a page. The page sends it to the server. The server compares it to its own computation and accepts. What has been proven is that the party who typed the code had access to the shared secret at that moment.
Notice what is absent. Nothing in that exchange describes what is being authorised. The same six digits would satisfy a login, a password change, a withdrawal to a new address, and the addition of a new authorised device, because the code is generated from a clock and a secret and knows nothing about the operation it is being used to approve.
That is why real time relay works so well. An attacker puts a convincing page in front of you, you enter your password and your code, and the attacker's infrastructure passes both to the real service within seconds. You have authenticated. The attacker has the session. Your authenticator app performed flawlessly and protected nothing, because the code you generated was never attached to the thing you thought you were doing.
This is the deeper point and it generalises well beyond SMS: improving the delivery channel does not address the problem, because the problem is not delivery. A code delivered by the most secure channel imaginable still proves only receipt. If you want to know that a person intended a specific action, the evidence has to be about the action.
Why is recovery the part nobody fixes?
Walk into almost any serious platform's security settings today and you will find a well designed authentication story. Passkeys supported. Hardware keys supported. SMS demoted or removed from login. It looks finished.
Then click the small link that says something like "can't access your authenticator" and watch the assurance level collapse. Very often the path leads to a code sent by text message, or to a support process that will accept one.
We have written about this pattern at length in the piece on passkey recovery, and the short version is that every strong authenticator ships with a weak path behind it, because users lose devices constantly and every organisation is under pressure to get them back in. The pressure is real: account lockout generates support cost, churn, and genuinely distressed people who have lost access to things that matter to them.
So the incentive gradient runs the wrong way. The security team hardens the front door because that is what gets measured, and the support organisation quietly keeps a key under the mat because that is what gets escalated. Both are behaving rationally within their own scorecards.
The result is that the attacker's optimal strategy is not to attack the authentication at all. It is to attack the reset. This is why a SIM swap remains dangerous at services that removed SMS from login years ago. The number is still a recovery factor, and recovery is where the account actually lives.
The way out is not to make recovery harder in a way that strands people. It is to change what recovery proves. Instead of re-establishing identity from scratch using whatever channel is available, recovery should re-establish continuity, which means proving that the person asking is the same person who enrolled. That argument is developed properly in our piece on recovery without the document upload, and the distinction between re-proofing and continuity is one of the more useful ideas in this whole area.
What does binding an approval to an action look like?
Here is the mechanical difference, and it is smaller than people expect.
In the code model, the server generates a random value, sends it somewhere, and waits for it to come back. The value is meaningless by construction, which is the point: it is a nonce, not a statement.
In the bound model, the server takes the actual operation being requested, serialises it in a form that both sides compute identically, hashes it, and asks the user's enrolled device to sign that hash. The signature is over the operation. If the operation changes by one digit, the signature does not verify.
Concretely, for a withdrawal, the thing that gets signed looks like this:
{
"action": "withdrawal.create",
"account_id": "acct_8812",
"asset": "USD",
"amount": "42000.00",
"destination": "ACH 021000021 / 000123456789",
"requested_at":"2026-09-23T14:02:11Z",
"nonce": "b0f1c2a9"
}
payload_hash = SHA256(canonical_json(payload))
assertion = webauthn.get({
challenge: payload_hash,
userVerification: "required"
})
The device shows the human what they are signing, in words, before the biometric prompt. The signature comes back and the server verifies it against the public key registered to that human, then stores the whole thing as a receipt:
verify(assertion.signature,
over: payload_hash,
with: enrolled_public_key) -> true
receipt = {
payload_hash, assertion, key_id,
verified_at, policy_version
}
Now consider the SIM swap attacker in this world. They hold the phone number. The number is irrelevant, because nothing was sent to it. They would need the private key, which never left the enrolled device's secure element, and they would need to satisfy the device's own user verification, which is a biometric or a device passcode. They have neither. The withdrawal does not proceed.
Consider the real time relay attacker. They can put a page in front of the user and capture anything the user types. But there is nothing useful to type. The assertion they would need to steal is bound to a payload hash that describes a withdrawal to the attacker's account, and if they present that payload to the user's device, the device shows the user a withdrawal to the attacker's account. The attack becomes visible at exactly the moment it has to happen.
That last property is worth pausing on, because it is the real prize. Binding does not merely make the credential harder to steal. It makes the attack legible to the person being attacked, at the moment of the attack, in plain language. Every other control in this space asks a human to detect a fake. This one asks them to read a sentence about their own money.
What does each factor actually prove?
It helps to lay these side by side, because the industry vocabulary flattens genuinely different guarantees into the single word "two factor".
| Factor | What it proves | Primary failure mode |
|---|---|---|
| SMS code | A message reached the number currently assigned to this SIM | Carrier reassigns the number through a supported retail process |
| Email code or link | Someone had access to the mailbox | The mailbox itself often recovers by SMS, so the weakness is inherited |
| Authenticator app code | Someone held the shared secret at this moment | Relayed in real time by a proxy page; not bound to any operation |
| Push approval | Someone tapped approve on an enrolled device | Approves an operation the prompt does not describe; fatigue and pretext calls |
| Passkey login | A private key on a specific device signed a login challenge | Excellent against phishing at login; the session it issues then carries all later authority |
| Action bound signature | This enrolled human approved this exact operation | A human who reads and signs anyway; a fully compromised endpoint |
Read the middle column downward and the progression is clear. Each row moves closer to describing a decision rather than an event. The last row is the only one whose statement mentions the operation at all, which is why it is the only one that survives an attacker who controls the channel.
How do you remove SMS without stranding people?
This is where most advice becomes useless, because it recommends deleting SMS and stops. In practice a large share of users have exactly one device, no backup, and no appetite for a hardware key, and a policy that locks them out has not improved security, it has moved the cost onto the least equipped people and generated a support queue that will be resolved by exception anyway.
A sequence that actually survives contact with an operations team looks like this, in this order, for reasons of difficulty rather than importance.
First, remove SMS from authorising high value actions
This is the cheapest change with the largest effect, because the set of actions is small and the affected population at any moment is tiny. Withdrawals to new destinations, adding a payee or a withdrawal address, changing bank details, adding an authenticator, changing the recovery email. These are the operations where an attacker converts access into loss. Require an action bound signature for these and leave everything else alone for now. Related reading on why the payee change matters more than the payment itself is in the payee add piece.
Second, keep SMS as a notification channel
There is a genuine and underrated use for SMS that survives everything in this post: telling the user that something happened. A message saying a withdrawal address was added, sent to a number, is useful even if the number has been swapped, because it is one more chance for the legitimate user to notice. Notification is a delivery problem, and SMS is a good delivery channel. The mistake was only ever using it as an authorisation channel.
Third, fix recovery last, because it is hardest
Recovery is last not because it matters least, but because doing it well requires something to fall back on that is not a document upload and not a support agent's judgment. That means enrolling a second factor or a second device for as many users as possible before you close the SMS path, and it means building a continuity based path for the users who will inevitably arrive with nothing. Closing SMS recovery before that exists simply converts account takeover risk into account lockout risk, and lockout is also a harm.
Honest limits
Several things this control does not do, stated plainly.
- It does not stop a person who genuinely intends the transaction. If someone is talked into authorising a transfer to a scammer, they will read the payload, understand it, and sign it. Binding proves intent; it does not evaluate whether the intent was well founded. Social engineering that persuades rather than impersonates is a different problem and needs different controls.
- It moves the trust to enrollment. The whole model rests on the right human being bound to the right key at the start. An attacker who is present at enrollment owns the account from birth, and no amount of later signing repairs that. Enrollment quality is the load bearing assumption.
- A fully compromised device defeats it. If malware controls the phone that renders the payload and holds the key, it can show one thing and sign another. Device security is a prerequisite, not something signatures replace.
- It adds friction, and friction has victims. Every additional step excludes somebody: people without smartphones, people with certain disabilities, people in the middle of an emergency. A design that ignores this is not more secure, it has just relocated the failure.
- It does not retrofit. Accounts that already have an attacker's authenticator enrolled are already lost, and no future control repairs a past compromise.
What to do this week
- Inventory every place SMS can authorise something. Not where it can log in, where it can authorise: resets, withdrawals, payee changes, authenticator enrollment, support overrides. Most teams are surprised by this list.
- Rank those endpoints by irreversibility, not by frequency. An operation that cannot be undone deserves a control that cannot be relayed, regardless of how rarely it happens.
- Check what your own recovery flow falls back to. Follow it end to end as a user with no access to the primary factor. Write down the weakest step. That step is your real security level.
- Separate notification from authorisation in your codebase. They are frequently the same function. They should not be. Notification can stay on SMS forever; authorisation should not be there at all.
- Push enrollment of a second factor before removing the first. Every user who enrolls a second device before you close the SMS path is a support ticket that never happens.
- Write down the support override procedure and count the humans who can execute it. If a support agent can bypass the control, the control is worth what that agent's judgment is worth under pressure. Our piece on bribed support staff covers why this matters more than it seems.
- Try the flow yourself on a spare account. Nothing reveals a recovery design faster than being locked out of it deliberately on a Wednesday afternoon.
If you want to see what an action bound approval feels like from the user's side, there is a working demonstration at the signing lab, and the integration shape is documented in the developer docs.
Frequently asked questions
Does SIM swapping still work if I use an authenticator app? For login, an authenticator app removes the carrier from the picture, so a SIM swap alone will not defeat it. The risk returns through recovery: if the service will send a reset code by text when you cannot access the app, the attacker simply takes that path instead. Check what your recovery falls back to, because that is your actual security level.
Are SIM swap attacks getting worse? Reported losses have fallen substantially, to roughly $17.4 million across 971 complaints in 2025 from a peak above $70 million in 2022 (FBI IC3 annual reports). Carrier rules and platform changes deserve credit for that. The residual risk is concentrated in rare, severe incidents at accounts where SMS still authorises withdrawals or resets.
What is the difference between authentication and authorisation here? Authentication establishes who is present at the start of a session. Authorisation establishes that a particular operation was intended. A one time code can contribute to the first and cannot address the second, because the code contains no information about the operation. Binding a signature to the operation is what turns a login into a decision.
Should we remove SMS entirely? Not as a first step, and not from notifications. Remove it from authorising irreversible actions immediately, keep it for telling users that something happened, and fix recovery last, after you have enrolled alternative factors widely enough that closing the SMS path does not lock out a large population.
Do carrier PINs and port freezes help? Yes. They raise the cost of the retail attack, and the drop in reported losses since the Federal Communications Commission adopted SIM swap and port out rules suggests the carrier layer genuinely improved. They do not change what a code proves once delivered, so they reduce one attack path rather than fixing the underlying design.
What about eSIM, does that change anything? An eSIM removes the physical card but not the reassignment process, which is the actual weakness. The carrier still owns the routing entry and can still move it. Some implementations add device binding that makes the transfer harder, which is an improvement at the margin rather than a change in kind.
Sources
- Federal Bureau of Investigation, Internet Crime Complaint Center, annual Internet Crime Reports, for SIM swap complaint counts and reported losses across 2022 to 2025: ic3.gov/AnnualReport/Reports
- Federal Communications Commission, rules addressing SIM swap and port out fraud adopted in 2023, requiring carrier authentication procedures and customer notification: fcc.gov
- National Institute of Standards and Technology, Special Publication 800-63B, Digital Identity Guidelines, on out of band authenticators and the treatment of SMS as a restricted authenticator: pages.nist.gov/800-63-3/sp800-63b.html
- World Wide Web Consortium, Web Authentication Level 2 specification, for assertion structure and user verification: w3.org/TR/webauthn-2
- FIDO Alliance, specifications and deployment guidance on device bound credentials: fidoalliance.org
- United States Department of Justice, press releases relating to SIM swap prosecutions, for the shape of charged schemes: justice.gov/news
A note on one widely repeated figure. A SIM swap features in reporting and charging documents connected to unauthorised access at a major cryptocurrency exchange in November 2022, and a large dollar amount is frequently attached to it in secondary coverage. The public record ties the swap to the intrusion rather than cleanly to a single transfer total, and the amounts are entangled with a bankruptcy, so we have not repeated a figure here. The shape of the incident is the instructive part: a retail reassignment preceded account access at an institution holding a great deal of other people's money.
A one time code answers "did this arrive". It has never once answered "did you mean this".