Don't know if I should share it here but hey, we all make mistakes :)
I had to implement a "forgot password" feature in a web application. I implemented it via:
1) Take the user's email
2) Generate a 6 digit code
3) Send the code to the email
4) Send the hash of the code to the frontend and save it in local storage
5) Compare the code from user which they get via email to the hash in local storage
Someone could change the hash in the local storage and bypass this.
Of course, I reverted to use Redis instead of local storage for this after like 3 days, fortunately with no mishaps.
I've since then made up my mind to not implement bad workarounds like this because it just felt so wrong.
In a security test of a bespoke password reset platform, I came across something quite similar, so you're not alone.
The JSESSIONID of the unauthenticated request for a password reset (as exposed to the client as a cookie) was used as the secret in the email sent to the user. Therefore an attacker knew the emailed token before it was even sent, and could reset the account password and take it over.
totp is good in theory but not ideal for sending via email. Users might miss the email, or it gets delayed, then they want to resend the email and end up with two codes or more. Which one to use then? and you might want bruteforce protection so you introduce a rate limit, which can lock users out in those scenarios.
I would not use a TOTP but a stateless HMAC token in this case. I was only evoking TOTP because the original comment mentioned a 6-digit code (which is not a proper way to reset a password).
I had to implement a "forgot password" feature in a web application. I implemented it via:
Someone could change the hash in the local storage and bypass this.Of course, I reverted to use Redis instead of local storage for this after like 3 days, fortunately with no mishaps.
I've since then made up my mind to not implement bad workarounds like this because it just felt so wrong.