Modern applications frequently use One-Time Passwords (OTPs) to confirm user identity when logging in, registering, changing passwords, or confirming transactions. They are created safely on the server, transmitted through a reliable channel (such as email or SMS), and are intended to be private, time-limited, and unpredictable.
However, the OTP is generated client-side in this insecure implementation, usually with JavaScript. Even worse, an attacker can easily intercept or alter the OTP because it is disclosed in the request or response (for example, in network logs, browser developer tools, or API responses).
Example:
Or even worse, the OTP is returned in an API response like:
This defeats the core security assumption behind OTPs — that the user must access a secure, separate channel to retrieve it.
This flaw has serious ramifications for account security and authentication:
To secure OTP workflows, applications must shift all OTP logic to the server-side and ensure secure delivery. Here's how: