csrf · high

CSRF + Open Redirect to Account Takeover

8 min read r29k

An atypical CSRF, found by luck, chained with an open redirect to silently plant an attacker's email on a victim's account.

I originally wrote this one on Medium and I'm moving it here with some improvements. The bug is a chain of CSRF and an open redirect that leads to full account takeover. The CSRF wasn't the typical kind, well, it was, in a way, but you'll see why it isn't, how I stumbled onto it, and how I chained it with an open redirect to bypass a "Successfully Added Secondary Email Address" pop-up. Let's jump in.

The setup

I picked a public VDP program from Bugcrowd and started without any recon, the scope was tiny and it was a VDP, so I didn't feel like doing recon. I went straight to the main app, created an account, and poked around to learn the features. I usually start from the account settings page, since that's where the easy bugs live: CSRF, IDOR, XSS, CSTI/SSTI (not actually easy :p). The first thing I tried was CSRF on the add-secondary-email feature.

The secondary email feature

You can add a secondary email to your account to receive updates, password reset tokens and so on, just like the primary. When you add one, you get a confirmation link, and you have to open it in the same browser where you're already logged in, otherwise the app asks you to log in first. Confirming redirects you to the account settings page with a pop-up: "Successfully Added Secondary Email Address".

Testing for CSRF

I added a second email and intercepted the request in Burp to check for anti-CSRF tokens. They were there. I forwarded it unmodified, got the confirmation link, opened it in the same browser, and the email was added as intended.

Now to check whether the server actually validated those tokens. I removed the secondary email and added it again, but this time I stripped the anti-CSRF token value, leaving the parameter empty. On forwarding I got a "No CSRF TOKENS" error, but then my phone beeped, and there was a confirmation link.

the weird part

I got a confirmation link for adding a secondary email without valid anti-CSRF tokens. The server returned the missing-token error and still sent the confirmation link anyway.

The twist

I was happy, and pretty sure this would be a duplicate, but it'd still earn some reputation, so no harm submitting. I made a second account to confirm and built a CSRF exploit, using a brand-new email this time, not the one from before. I ran it, got the missing-token error, waited for the link, and got nothing. I ran it again and again on both accounts, still nothing. I figured maybe there was an anti-CSRF header I'd missed, but checking the request, there wasn't one.

So I went back to my first account and tried adding the same email I'd used during the earlier CSRF testing. I removed the token, got the error, and got the confirmation link. That gave me an idea: use that already-added email in the exploit. I dropped it in, ran it on my second account, and the confirmation link came through.

root cause

Adding a brand-new email without CSRF tokens gives only an error. But adding an email that's already been tied to an account as a secondary, without tokens, gives the error and a working confirmation link.

The remaining problem: the pop-up

There was still a catch. An attacker can't use the confirmation link without being logged into the victim's account. What they can do is send the link to the victim, and when the victim opens it, the attacker's email gets added to the victim's account. But the victim would see the "Secondary Account Added Successfully" pop-up and realize a new email had been added. I couldn't think of a way around it. And since I assumed someone had already reported this and mine would just duplicate, I didn't want to burn time on it (I was completely wrong). I submitted with repro steps and the CSRF exploit.

The report saga

The program's expected response time was 30 days. After 23 days they replied that they couldn't reproduce it. I was busy on another program and didn't respond, not knowing that failing to reply within 15 days closes the report as N/A. So it got closed as N/A, and I didn't feel like redoing the PoC.

Four months later I was going through my old reports, found this one, and tried again. The CSRF was still there. I commented that it still worked, and they asked for a working PoC. It worked for me but not for them. I spun up a fresh account to test, and it worked, and this time I noticed something I'd missed: a redirect parameter in the confirmation link, set to /profile/settings, the page where the pop-up fires.

The open redirect bypass

I wondered what would happen if I redirected the user somewhere else, like /home. Would they still get the notification? I changed redirect to /home, opened the link, landed on the home page, and the notification never popped. I checked the account settings, and my secondary email was sitting right there. That was the bypass for the "Successfully Added Secondary Email Address" pop-up.

Attack scenario

Say the attacker controls attacker@gmail.com and wants it added to the victim's account via CSRF:

  1. Add attacker@gmail.com to the attacker's own account the normal way and confirm it.
  2. Remove the email. It's now "primed" for use in the CSRF exploit.
  3. Build a CSRF exploit using attacker@gmail.com and send it to the victim.
  4. When the victim runs the exploit, the attacker receives a confirmation link on their own email.
  5. The attacker changes the redirect parameter to /home and sends that link to the victim.
  6. When the victim opens it, the attacker's email is added to the victim's account with no pop-up, since the victim lands on the home page instead of profile settings.

With a secondary email now silently attached to the victim's account, the attacker can request password reset tokens to that address and take the account over.

Outcome

I wrote a clean report and submitted it under the same ticket. The triager ran the exploit, got a confirmation link, I modified the redirect parameter and sent it back, and when he opened it my email was added to his account. He marked it P3 because of the user interaction, apologized for the long delay, and invited me to file the same report in their private program. The next day the private invite arrived, they paid for P1, P2 and P3 there, I submitted the same report, and they triaged it P2, partly for the finding and partly for the patience, and paid a four-figure bounty I wasn't expecting at all.


Questions or feedback? Reach me on Twitter @R29k_, or on Discord at Demon#1841. Thanks so much for reading, see you in the next one.

more writeups
Account Takeover via Chained IDORs Wayback Machine to Account Takeover Account Takeover by Chaining Two IDORs
← all writeups