Prevent validation using old OTP after resending new OTP

Created on 14 August 2025, about 1 month ago

Problem/Motivation

After clicking 'Resend OTP', if the user enters the previously issued OTP, they are still able to validate and log in to the site. This creates a security issue because outdated OTPs remain valid.

Steps to reproduce

  1. Request an OTP for login.
  2. Before entering it, click 'Resend OTP' to generate a new one.
  3. Enter the original (old) OTP instead of the new one.
  4. Observe that login still succeeds.

Proposed resolution

Invalidate any previously generated OTP immediately when a new OTP is issued. Ensure that only the latest OTP can be used to validate and log in.

Remaining tasks

  • Review and test the provided patch.
  • Verify that old OTPs are rejected after resending.
  • Confirm no regressions for normal OTP flow.

User interface changes

None.

API changes

None.

Data model changes

None.

๐Ÿ› Bug report
Status

Active

Version

2.0

Component

Code

Created by

๐Ÿ‡ฎ๐Ÿ‡ณIndia radheymkumar Jaipur, Rajasthan, India

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @radheymkumar
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia radheymkumar Jaipur, Rajasthan, India

    Please review and apply this patch

  • ๐Ÿ‡ธ๐Ÿ‡ฆSaudi Arabia abdulaziz zaid Riyadh

    I checked the code and confirmed that when a new OTP is sent, it simply overwrites the old one in storage. This means the previous code is no longer valid and cannot be used. The module already works as expected, so no change is needed

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia radheymkumar Jaipur, Rajasthan, India

    I resent OTP but my first time login OTP also remains validated.

  • ๐Ÿ‡ธ๐Ÿ‡ฆSaudi Arabia abdulaziz zaid Riyadh

    I re-tested this on my side, and the OTP flow works as expected:

    The hash is constant (user ID + username + password hash + site salt).

    As a result, every new OTP is stored under the same key.

    This means the new OTP always overwrites the old one, so the previous code should not validate.

    It would be really helpful if you could share a bit more about your setup so we can understand why you are seeing a different result:

    Which version of the email_tfa module are you using?

    The exact steps you followed when both codes worked.

    With these details, we can better reproduce your case and confirm if thereโ€™s a specific scenario causing this behavior.

    Thanks,
    Abdulaziz

Production build 0.71.5 2024