Design and harden SMS one-time password (OTP) risk controls: send/resend budgets, verify attempt limits, code entropy and TTL, purpose binding, and abuse-resistant UX. Use when login, signup, step-up, or recovery relies on SMS OTP and you need send-flood, brute-force, enumeration, and binding controls for owned applications or authorized remediation.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Design and harden SMS one-time password (OTP) risk controls: send/resend budgets, verify attempt limits, code entropy and TTL, purpose binding, and abuse-resistant UX. Use when login, signup, step-up, or recovery relies on SMS OTP and you need send-flood, brute-force, enumeration, and binding controls for owned applications or authorized remediation.
SMS OTP Risk Controls
Engineering controls for SMS-delivered OTPs: when to send, how often, how
codes are generated and bound, how verification fails safely, and how residual
carrier/SIM risk is documented. Prefer stronger factors (WebAuthn, TOTP) where
product allows; when SMS is required, make it hard to flood, guess, or reuse.
Scope And Authorization
Design/implement on systems you own or are contracted to change.
Authorized assessment only: dual test accounts you control; never trigger SMS
or complete OTP for third parties; cap volume (cost and lockout risk).
Do not perform SIM-swap, SS7, or carrier fraud research against real users.
Redact phone numbers (partial mask), full OTPs, and session tokens in reports.
Normalize and bind identity. Store phones in E.164. Bind each challenge
to user_id (or pending signup id), normalized MSISDN, purpose
(login | signup | reset | step_up | phone_change), and short
TTL. Reject codes for wrong purpose or expired challenges. Prefer opaque
challenge_id over accepting raw phone+code alone on privileged paths.
Hash at rest (or encrypt); never log plaintext OTP
Lifetime
Short TTL (e.g. 5–10 min); one active challenge per purpose
Use
Single-use; invalidate on success and on superseding resend
Compare
Constant-time; fixed failure shape
Send / resend budgets (cost and harassment). Dual-key: per destination
MSISDN and per account/session and trusted IP ceiling. Cooldown
between sends (e.g. 30–60s); daily/hourly caps per MSISDN and per initiator.
Resend and voice share the same budget class. Provider webhooks: verify
signatures; do not expose full OTP in callbacks or admin UIs.
Verify budgets (online guessing). Short codes need strict attempt
limits (e.g. 3–5) then invalidate challenge and require resend; progressive
delay; dual key account + IP. Atomic counters. Align hard lockout with
account-lockout-design; soft volume with api-rate-limit-design.
UX and enumeration. Prefer generic “If eligible, a code was sent” and
stable timing for known vs unknown phones where product allows. Do not return
remaining attempts or “code was X digits.” Support paths must not reveal OTP.
Session and elevation. Issue or upgrade session only after server-side
success; rotate session id at factor-2. Never trust client flags
(otp_ok, sms_verified). Step-up again for phone change, disable MFA, and
high-risk actions. Residual SIM-swap / SMS intercept: document; prefer TOTP /
WebAuthn for high-value accounts.
Tests and ops (code-quality-standards). Unit/integration: expiry, reuse,
wrong purpose, attempt lockout, resend invalidates old code, E.164 bucketing,
no OTP in logs/metrics. Alerts: send spike per route, verify fail spike,
provider error rate. Fail-closed or CAPTCHA when counter store is down on
auth paths.