CSRF
Summary
CSRF at its core is attempting to get an application to perform some action at the behest of an attacker controlled domain. The user is often unaware of the underlying executing JavaScript and merely requires the user visit an attacker owned link. Sending requests in this way can bypass some Same Origin Policy (SOP) protections and is only limited by what the application is capable of.
When looking to exploit CSRF it is important to find functions that would warrant control of, such as changing user permissions or user data. Then there must be some session cookie as other forms of authorization prevent CSRF. And finally the parameters and fields must be predictable.
Although XSS - JavaScript Injection and CSRF - Cross-Site Request Forgery both end up executing JavaScript, Cross-Site Scripting can be stored on the vulnerable web application, lending to far more dangerous attacks and more sophisticated scripts. CSRF in a way is a one way exploit where you control the request and nothing else. It can be exploited by bypassing token validation, SameSite restrictions, and referrer based defenses.
Methodology
When looking for CSRF vulnerabilities ask/try the following:
- Is there any function worth making another user perform?
- Does this function have a CSRF token?
- try changing method to GET without the token
- try removing the token
- try submitting one user’s csrf token for another
- try submitting another form’s csrf for a different one
- Is the csrf token in a cookie?
- check if the csrf token is reflected within the cookie
- if yes change both to something arbitrary
- try removing the cookie
- try an invalid cookie
- submit a cookie from another user
- add submitting a token from another user if successful
- Is there a place to set cookies?
- check subdomains for functionality
- if url-based try appending
%0d%0aSet-Cookie:%20csrfKey=asdasd%3b%20SameSite=None
- check if the csrf token is reflected within the cookie
- Are SameSite restrictions set?
- Is it Strict?
- probably nothing here
- Is it Lax (chrome default*)?
- try changing the request method to GET
_method
can be used in some frameworks<input type="hidden" name="_method" value="GET">
- within a url can use a GET request with
_method=POST
- try to override with
X-Http-Method-Override: GET
- Are there any subdomains or gadgets that craft requests for me?
- check WebSocket for potential vulnerabilities
- change
Origin
on handshake and try CSRF from there
- change
- check WebSocket for potential vulnerabilities
- check if Lax is specifically set or if it is set by browser
- if not set deliberately there is a 120 second window after cookie creation where its vulnerable
- specifically the restrictions of being a POST and from a top-level domain don’t exist
- use
window.onclick
orwindow.open
to refresh cookie on a page
- if not set deliberately there is a 120 second window after cookie creation where its vulnerable
- try changing the request method to GET
- Is it None (must have the Secure attribute)?
- investigate further for any possible use
- Is it Strict?
- Are there referer header based protections?
- try removing the header entirely
- try appending a malicious domain with ?
- for CSRF make sure the
Referrer-Policy: unsafe-url
header exists- use
history.pushState('', '', '/?URL')
adds a url to the history for referrer
- use
Capabilities
Request Forgery
Replicating User Actions
Found In
User Input
Tools/Examples
https://csrfshark.github.io/app/ simple email changing request
<html>
<body>
<form action="https://vulnerable-website.com/email/change" method="POST">
<input type="hidden" name="email" value="pwned@evil-user.net" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
window opening on user click w/o leaving page
window.onclick = () => { window.open('https://vulnerable-website.com/login/sso'); }
Mitigations
CSRF tokens for forms
High entropy, tied to a session, and validated in every case before execution
Store server side in user data, then validate against, if failed to validate reject request
SameSite cookies to prevent other sites using cookies in a request
SameSite: Strict
, lower to Lax if there is a good reason, steer clear of None
Referer-based validation to make sure the request is from the application’s domain