Skip to content
Nirmal Dahal

26 Nov 2019 · 1 min read

Reflected XSS leading to CSRF bypass and account takeover

How a reflected XSS was chained to steal a CSRF token and change a victim's password, bypassing CSRF protection to take over the account.

By Nirmal Dahal

Diagram of reflected cross-site scripting: the attacker sends a link, the user's browser runs it and sends data back
On this page

I was testing one web application and going through error parameters and then found a Reflected XSS.

http://Redact/Redact.EXT?errorMsg={Vulnerable-Endpoint} (opens in a new tab)

I did not think to find an R-XSS was the kind of critical vulnerability I was looking for. Next, I was going to go for CSRF but the site had CSRF protection so that was not possible. Continuing my search, I stumbled upon a page where you could change passwords but there was no "Old Password" field. Due to the CSRF protection, an attacker could not remotely change to a new password. Then I had an idea and started working on a script.

Sublime Text showing script.js that reads the _csrf token and sends it via XHR to process.php before redirecting

This script was created to steal the CSRF Token value from the web application. Using AJAX, the CSRF Token was sent to process.php, write stolen token in write.php finally then redirect it to csrf.php

Sublime Text showing write.php, which stores the CSRF token stolen from the victim

When the target was redirected to csrf.php, the form used to get auto-submitted. The form contained CSRF token from write.php. After the target clicked on the R-XSS link, it stole the CSRF token and simultaneously changed the password.

Sublime Text showing csrf.php, a hidden password-change form that embeds the stolen token and auto-submits via JavaScript

Result

Using the R-XSS vulnerability and couple line of JS and PHP I was able to steal the CSRF token and change the password of the victim.

P.S.

The initial script was very long because I was in a rush but this short final version can also be used to recreate this POC.

The shorter final script.js POSTing a new password together with the stolen _csrf token to changePassword

Request

HackBar holding the reflected-XSS URL whose errorMsg parameter injects the attacker's script tag

DevTools request showing the forged changePassword POST payload carrying the new password and captured _csrf token

Thank you for reading this article…

Happy Hacking :)

Let's scope it together.

Tell me what you need to protect and by when. I'll reply with whether I can help and how I'd approach it.