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.

practitioner · 4 min read · Lesson 5 / 8

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.

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

  1. Application
  2. SMPP gateway
  3. SMSC
  4. HLR / HSS
  5. MSC / MME
  6. Handset
  7. Delivery receipt
The same chain that delivers the code also creates the places where it can be observed, delayed or sent to the wrong handset. Source: 3GPP TS 23.040: SMS architecture
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

Each metric answers a different question. None of them measures identity.
MetricDefinitionWhat it tells you
Delivery rateDelivered receipts divided by submitted messagesWhether the network accepted the message; not whether a person read it
Completion rateCodes entered divided by delivered messagesWhether the message and the form worked for the user
Time to deliverMedian and 95th percentile from submit to receiptWhether the route is slow, and how long a user waits before resending
Resend rateResends divided by delivered messagesWhether users wait too long, mistype, or never see the first message
Block rateRequests rejected by risk rules divided by attemptsWhether 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

  1. 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.

  2. 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.

  3. 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?

An OTP can be the second factor. On its own it is one factor: possession of the number at that moment.

Are longer codes safer?

Length helps against guessing, but it does not stop a SIM swap, forwarding or phishing. Add a second check for high-value actions.

Can a delivery receipt prove the user read the code?

No. It reports a network state such as delivered, expired or undelivered. It says nothing about reading or typing.

Should we resend automatically?

Resend on a user action, not on a timer. Automatic resends multiply cost and can mask a route problem.

What should we log?

The request, the submit and its message ID, the receipt and its state, and the code entry result. Keep them as separate events with timestamps.

Receipts say delivered but users get nothing. What should we check before switching provider?

Your own side first, because a delivery receipt says the network accepted the message, not what the handset showed. Run the template through the SMS content pre-check, count its segments with the SMS segment counter, and read the submit and receipt codes with the SMPP and DLR code decoder. If those are clean, test the failing destination on your own handsets before you move traffic, one destination at a time.
  • 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.

Put this to work

Tell us the traffic, the destination and the measurement you need; we reply with the next step.