OTP SMS delivery and fraud
Where one-time passwords leak, what a delivery receipt can and cannot tell you, and the controls and metrics that keep an OTP flow working.
A one-time password proves control of a number at the moment it is entered. It does not prove identity, and a delivery receipt does not prove that a person read it. Delivery, interception, number recycling and the form itself decide whether the check holds.
Key facts
- An OTP proves control of a number at that moment, not identity.
- A delivery receipt reports a network state, not that a person read the code.
- Number recycling, SIM swap, forwarding and phishing are the main ways a code leaks.
- Rate limits, sender registration and number checks reduce abuse; none proves identity.
On this page
What an OTP proves
An OTP answers one question: can the person in front of you receive a message on this number right now? That is useful for account recovery and login, because it ties the session to something the user controls. It is not an identity document. The number can be recycled, moved to a new SIM, forwarded, or read by someone else in the household.
The distinction matters at the design stage. If the action is low value, an OTP is proportionate. If the action moves money, changes a password or adds a payee, pair the code with a second check: a delay, a confirmation in an existing session, a call-back to a known channel or a manual review. The code is one factor, not the whole decision.
The path, and the places a code can leak
- Application
- SMPP gateway
- SMSC
- HLR / HSS
- MSC / MME
- Handset
- Delivery receipt
Text description
The application submits the code to a gateway, the message center looks up the subscriber, and the serving switch delivers to the handset. A receipt returns on the same chain. A code can leak at the application, at the handset, at the number itself or through the person who receives it. The network path explains the delivery; it does not explain the human who shares the code.
Where an OTP leaks
A SIM swap moves the number to a new card. The attacker persuades a store or a support line that they are the owner, and the next code goes to the new SIM. Number recycling has the same effect without an attacker: a carrier reassigns a dormant number, and the new holder receives a code meant for the old account. Both are reasons to check whether a number was recently ported or reassigned.
Forwarding and voicemail-to-text send the message to another inbox. Phishing copies the form and collects the code directly, so the network never sees an attack. Interception on the network path is rarer and outside the application's control; the practical response is a second factor, not a longer code. Read the OTP glossary entry for the definitions.
Controls that help
Limit how often a number, an IP address and a device can request a code. Use a short validity, one use per code, and bind the code to the session that requested it. Register the sender and keep the content plain: a code that looks like marketing may be filtered, and a filtered code produces a support ticket, not a login.
Check the number before you trust it. A number that cannot receive SMS, was ported recently or has a history of resets deserves a second step. For high-value actions, require an existing session or a second channel. Log the request, the submit, the receipt and the code entry as separate events, so you can tell a delivery problem from a user problem.
Design the code itself with the same care. Generate it from a cryptographic source, store a hash, expire it in minutes, allow one successful use and cap the attempts per code and per session. Do not reveal whether the number exists. Create the account record before the send, so a retry cannot open an account that never completes.
Five metrics, with definitions
| Metric | Definition | What it tells you |
|---|---|---|
| Delivery rate | Delivered receipts divided by submitted messages | Whether the network accepted the message; not whether a person read it |
| Completion rate | Codes entered divided by delivered messages | Whether the message and the form worked for the user |
| Time to deliver | Median and 95th percentile from submit to receipt | Whether the route is slow, and how long a user waits before resending |
| Resend rate | Resends divided by delivered messages | Whether users wait too long, mistype, or never see the first message |
| Block rate | Requests rejected by risk rules divided by attempts | Whether the rules are too tight, too loose, or the traffic is abusive |
Track them by market, sender and route. A single global average hides the route that is failing.
Measure the flow, not the send
A send that returns a message ID is not a delivered code. A delivered code is not a completed login. Build the funnel from the events you control: submit, receipt, code entry, success. Then compare it with the provider's view. A gap between your delivery rate and the provider's may be a receipt that never reached your handler, not a message that never reached the handset.
Review the flow when a metric moves. A drop in completion with a stable delivery rate points to the form, the code expiry or the sender. A drop in delivery with a stable submit rate points to the route, the number or the content filter. A rise in resends points to time to deliver. Fix the step the data names, not the step that is easiest to change.
Set a review date for the whole flow. Numbers change hands, routes change and templates age. A flow that worked at launch can fail quietly six months later, with the same code and the same provider.
Check what you learned
-
A user forwards the code to a friend. Does the code still prove identity?
No. It proves that the number could receive the code at that moment. Anyone who has the code can use it.
-
A receipt says delivered, but the user never sees the code. What do you check?
The handset state, the messaging app and spam filter, the sender, and the route. A delivered receipt is the network's state, not the handset display.
-
Why is completion rate more useful than delivery rate?
Delivery stops at the network. Completion includes the user, the code expiry and the form, which is where most failures show up.
Answers are revealed on request. Nothing is scored, stored or sent.
FAQ
Is an OTP the same as two-factor authentication?
Are longer codes safer?
Can a delivery receipt prove the user read the code?
Should we resend automatically?
What should we log?
Receipts say delivered but users get nothing. What should we check before switching provider?
Terms you'll meet
Related
- Connecting over SMPP and HTTP
Take a test route to production without breaking binds, windows or receipts: bind, throughput, keep-alive, encoding, callbacks and failure handling.
- RFQ and RFP template pack
Field lists for SMS wholesale, eSIM and data, IoT and China connectivity requests, plus the online checklist that sends as an RFQ.
- Route test sample report
A desensitized static sample of a route-test report: what a route test checks, how failures read, and what triggers a route review.
Related products
Put this to work
Tell us the traffic, the destination and the measurement you need; we reply with the next step.