June 23, 2026
How I Found an Email Verification Bypass by Reusing a Verified Validation ID
While testing an account registration flow, I came across an interesting business logic issue that allowed me to bypass the email…
By Yahiaemara
1 min read
While testing an account registration flow, I came across an interesting business logic issue that allowed me to bypass the email verification process completely.
The application required users to verify their email address before finishing registration. At first glance everything looked fine: a verification code was sent to the email address, the code had to be entered, and only then could the registration continue.
After looking more closely at the requests, I noticed that the application was using a parameter called email_validation_id during the verification process.
Initial Observation
I created an account using my own email address and completed the verification process normally.
While intercepting the requests with Burp Suite, I noticed the following value:
{
"email_validation_id": "000000000-0000-0000-0000-00000000"
}{
"email_validation_id": "000000000-0000-0000-0000-00000000"
}At that point I became curious about how the backend was validating this identifier.
Was it actually linked to my email address?
Or was the application only checking whether the identifier itself was valid?
Testing the Theory
To answer that question, I started a new registration using a different email address.
I proceeded through the registration process until the final account creation request.
Before sending the request, I intercepted it and replaced the newly generated email_validation_id with the one that belonged to my already verified account.
The modified request looked something like this:
{
"email_validation_id": "000000000-0000-0000-0000-00000000"
}{
"email_validation_id": "000000000-0000-0000-0000-00000000"
}I forwarded the request and waited for the response.
The account was created successfully.
The email address used during registration had never been verified.
What Went Wrong?
The issue was not related to the verification code itself.
The real problem was that the backend trusted the supplied email_validation_id without verifying that it belonged to the email address currently being registered.
In other words:
- I verified Email A.
- I obtained a valid
email_validation_id. - I reused that identifier while registering Email B.
- The application treated Email B as verified.
The verification state was effectively transferable between accounts.
Impact
Although this might sound simple, it completely breaks the purpose of email verification.
An attacker could create accounts using email addresses that were never verified and potentially abuse any functionality that relies on verified email ownership.
Depending on the application, this could lead to:
- Fake account creation
- Abuse of registration limits
- Trust issues in email-based workflows
- Circumvention of anti-spam controls
Fix Recommendation
The fix is straightforward:
Every email_validation_id should be tightly bound to the email address for which it was issued.
Before completing registration, the server should verify that:
- The identifier belongs to the same email address.
- The identifier has not already been used.
- The identifier was issued during the current registration flow.
Client-supplied verification state should never be trusted on its own.
Final Thoughts
This was a good reminder that security issues are not always caused by complex vulnerabilities. Sometimes a small logic mistake is enough to completely bypass an important security control.
In this case, the verification process itself worked correctly, but the backend failed to verify the relationship between the email address and the validation identifier, making the entire email verification mechanism ineffective.