From staging to 0 click account takeover

mohamad mahmoudi
2 min readOct 20, 2021

Often, as bug bounty hunters or pentesters, while doing our recon on a specific target, we come accross their staging or pre-production environments. And if we look at these from the right angle, hidden gems could be waiting for us.

I was hunting on a private bug bounty program with a wild scope, let’s call it *.akme.com for obvious reasons. I started with subdomain enumeration when 3 subs caught my attention:

  1. dashboard.akme.com
  2. dashboard-staging.akme.com
  3. forms.akme.com
  4. api.akme.com

After few hours clicking around, I took the following notes:

  1. dashboard-staging.akme.com is the staging version of dashboard.akme.com(did not take much thinking)
  2. You can create an account on both of them, most importantly with the same email(this will come in handy)
  3. An account gets created for you automatically on forms.akme.com when you signup on dashboard app and you can login to it by hitting this endpoint with your jwt session: api.akme.com/oauth

4. You don’t need to confirm your email on dashboard.acme.com to login to forms.akme.com through oauth

Looking at these notes, I thought about the following scenario:

  1. Create an account A in dashboard
  2. Create an account B in staging-dashboard
  3. Login to forms with account A, by hitting the oauth endpoint with my user session
  4. Login to forms with account B(same process as 3).

The desired outcome was making account B login to account’s A forms account without knowing his password. It did not work at first try, instead took me to forms-staging which is the staging version of forms app. FAIL!

Try harder:

Looking at my burp history, I found that there is a parameter that gets added to the oauth request each time. Which, if you are logging from dashboard, becomes :

api.akme.com/oauth?referer=dashboard

And if you are logging from dashboard-staging:

api.akme.com/oauth?referer=staging-dashboard

So I tried intercepting the traffic while doing the same steps(account A is vicitm account B is attacker) but changing the value of the ?referer to dashboard while using my staging jwt session(user B). And guess what ! I got redirected to our victim’s account.

This exploit was possible for two reasons:

  • The developers used the same jwt secret to decode the session of the users. This allowed me to access the account of anyone on forms.akme.com by knowing their email.
  • You don’t need email confirmation to login with oauth, otherwise if you were not to prove that the victim’s email belongs to you, you wouldn’t be able to fully signup on dahsboard-staging with is the main vector of the attack

Worst part is I found another way to mass leak emails of other users, not an sql injection, maybe we’ll leave it for another article.

Hope this was a good read !

--

--