XSS killed the anti-CSRF star

This entry hopes to be a quick consideration about how one attack vector can at times dismantle the security of a different area of the application that was otherwise deemed secure. Truth is, security threats many times work like this, one thing builds upon another until, in the end, the attacker is able to score. In this case, I’ll show a real life example of how a DOM XSS flaw can be the only leverage an attacker needs to bypass a random token based CSRF protection. As a cherry, we’ll see that this effectively lead to account theft.

There’s been many a time that developers don’t fully understand that a «small» flaw can compromise the whole application if used with wit. In this case, it wasn’t even necessary to string many flaws. It sufficed with one used in the right spot to compromise the application.

The story goes as follows. We have a rather secure web application, with no major session management issues, and a settings page that looked something like this.

CSRF protected settings page

CSRF protected settings page

As shown in the image above, the application’s settings page contains an anti CSRF token that is random per request, and therefore it’s not vulnerable to CSRF attacks, or is it? The only flaw this application had was a DOM XSS present in every page -settings inclusive- that was considered «not critical» by the developers. But as is well understood by web pentesters, XSS flaws enable attackers to bypass CSRF token protections. The simple idea beneath is that the attacker can use the injected script to read the DOM, obtain the CSRF token and use it to make the right request to the server. Let’s take a closer look at this DOM XSS.

For every section of the application, a message indicates where within the application the user is. This has been implemented using a small JavaScript snippet that takes the URL and prints it on the screen. The code used was like this:

function printArea(){
var x=document.getElementById("area");
var u = window.location.href.toString();
area = u.substring(u.lastIndexOf("//")+2);
x.innerHTML = "You are in " + area +"<br \>";
The vulnerability is obvious, since there’s no encoding of the URL (window.location.href) and it can be manipulated by an attacker. A simple payload like #<img src=1 onerror=alert(42)> appended to the URL triggers the flaw as can be seen in the screenshot below.
Triggering the DOM XSS

Triggering the DOM XSS

Nothing surprising here. Pretty easy, straight forward DOM XSS. How can the attacker use this to launch a CSRF attack then? Simple, the attacker would add into the URL JavaScript code that reads the CSRF token from the DOM, builds a POST request (the web doesn’t work with GET) and sends it. The server would have no way to tell the legitimate user’s request from this one. To get the token, the following line can be used:


Reading the anti CSRF token

Reading the anti CSRF token

All the attacker needs to do now is put together a small piece of code to use that token to submit a request. The following code worked for the above vulnerability:

var http=new XMLHttpRequest();
params='email=attackersemail@gmail.com&phone=0888888888&address=123 Fake Street&csrf_token='+token+'&submit=';
http.setRequestHeader('Connection', 'close');
That script (can be simplified), URL encoded, can be used to attack a legitimate user and force him into submitting the form and thus modifying email/address/phone to one of the attackers choosing. Nothing too exciting though, until you put all the pieces together. The developer classified this as low risk, since in his opinion editing those settings won’t take the attacker anywhere. However, he failed to see, that the expected behaviour of his application would allow the attacker to access other people’s accounts. How so? Easy, the application has a «Reset Password» functionality with no vulnerabilities at all, that looked like this.
Email the user a new password

Email the user a new password

If the user cannot remember his password, all he/she has to do is enter his username in the text field (and captcha), and he will be sent an email with a new temporary password to the email account specified on his settings page. The attack vector should be crystal clear now:

  1. Attacker lures victim to click on a link with the above XSS payload in the URL
    1. The payload submits a request to the page bypassing the CSRF protection, changing the account email to the attacker’s one
  2. If need be, the payload is tailored to also send the username to the attacker (i.e. making a GET request to his evil server)
  3. The attacker visits the «Reset Password» page, introduces the victims username.
  4. The attacker receives a new password for the victims account, and effectively steals it.

If the settings page were using another anti CSRF technique, like Capthas or asking the user for credentials would still have been possible, although a little bit more tricky.

This is nothing new or technically complex, but I felt like pointing it out since I find many people fails to connect the dots to achieve their goals with the vulnerabilities they find. At the same time, many developers aren’t aware that a XSS can turn into a session management issue.

Tagged with: , , ,
Publicado en web hacking

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

A %d blogueros les gusta esto: