Is SMS OTP still worth the risk?

SMS OTP is the default second step for a huge number of products. it’s familiar, users get it, and it works on every phone.

But the more I look at it, the more it feels like a decision most teams made years ago and never revisited.

The risks are not hidden. SIM swaps let someone take over a phone number and receive your codes. Messages can be intercepted or delayed. And then there’s sms pumping, where bots hammer your signup form to trigger codes to numbers they control, and you end up paying for every message.

That last one is the one that surprises people. It’s not a security breach in the usual sense, nobody got into an account. It just shows up as a strange spike on the bill.

And yet it’s hard to drop. Users trust it, and not everyone has an authenticator app or a device that supports passkeys. so it stays, usually with no limits around it.

Curious where teams land on this. Do you still rely on sms otp, and if so, what do you do to protect it? Rate limits, region restrictions, something else? Or have you moved off it entirely?

16 views

Add a comment

Replies

Best

SMS OTP is still useful for accessibility, but relying on it as the only security layer feels risky. Do you think passkeys will become the default for most products?

 i think yes, eventually, but ‘eventually’ is doing a lot of work 😄
sms will stick around as the fallback for years because of exactly the accessibility point you made. so the practical move is probably passkeys first, sms as the backup, and limits around the backup. always up for comparing notes with people working on similar problems, happy to chat if that’s you:)

sms pumping is an underrated problem because teams often notice it through billing rather than security alerts. Rate limits and phone verification can help, but how do you balance protection with a smooth signup experience?

 honestly the billing spike is how most teams find out 😅 so the cheapest balance is to put the friction at signup, before a code ever gets sent. block country prefixes you don’t serve, cap sends per number and per ip, and let real users through untouched. most pumping traffic comes from a few regions nobody expected to have users in. if you’re in a similar space, would love to swap notes sometime.

From the design side, most of the drop-off I see around OTP isn't the method itself, it's the small details around it. No autofill on the code field, a resend button with no visible countdown, an error that just says "invalid code" without saying whether it expired, a back button that wipes the phone number you just typed. Those get blamed on impatient users when it's really the flow. If you add rate limits or region blocks, I'd make the blocked state say what happened and offer a second route (an email link, say), because a silent failure looks exactly like a broken product.

 this is such a good point, and the ‘invalid code’ with no hint on whether it expired is painful 😭 and yes to the silent failure thing. a blocked user and a broken product look identical from the outside, so the second route is half the fix. a lot of ‘security friction’ complaints are really bad error copy. if you’re working in this space too, would love to trade notes.