Suppose I want to implement an OTP system that generates 6 to 10 digit numbers. (assume its used for reset password, or send money)
The OTPs have an expiry time, so they keep getting removed from the server's memory.
I have been looking around the Internet but could not find a single reference to the following best practice:
The "attacker/user" must supply the email along with the OTP to use it.
The reason I am asking is because I have a colleague who want to implement the OTP as follows:
- Generate OTP, store (OTP, email, expireTime, purpose) in server memory. If same OTP is generated again, the old entry is removed from memory.
- Send OTP to email.
- Ask ONLY OTP input from user (example /verifyEmail?OTP=100434).
- Get the (email, purpose) from server memory for the OTP
- Use the OTP for the purpose
I could not convince him that this is insecure as an attacker can simply generate random OTPs and call the routes, and automatically cause some actions. ("The OTP only expires in 3 mins", "only once in a while it will be an issue", "We used it in another project and it was fine", etc).
What I need is a blog post or article (not too technical) that explains WHY this is insecure.
Also, what are the ways to implement a good OTP system of 6 to 10 digits?
Is random OTP generation good enough?
My suggestion would be to require only (email, OTP) pair uniqueness rather than OTP uniqueness and require email + OTP to be supplied by user. Is this secure?