This post is part of the series 'Vulnerabilities'. Be sure to check out the rest of the blog posts of the series!
#What's XSRF?
CSRF (Cross-Site Request Forgery) vulnerabilities allow an attacker to impersonate a user and perform requests on a website on their behalf. This happens when a website lets authenticated users perform sensitive actions without verifying that the user intentionally triggered them. Instead, it only checks that the request originates from the browser of an authorized user.
The attacker's goal is to exploit the authentication cookie already stored in the browser for the targeted website. To do this, they simply need to trick the browser into sending a request to the target site. There are several ways to achieve this:
- Convincing the user to click on a malicious link,
- Injecting HTML or JavaScript into a page the user visits. For example, an image tag whose source URL triggers an action on the targeted site:
<img src="https://example.com/delete/1">. When the browser encounters an img tag, it fetches the source via a GET request, inadvertently triggering the action.
One might think that replacing all GET actions with POST would be sufficient. It is not. An attacker can still use JavaScript:
HTML
<body onload="document.getElementById('form').submit()">
<form id="form" action="https://example.com/delete/1" method="post">
<input name="delete" value="Delete" />
</form>
</body>
The form is submitted automatically using the POST method. While this is slightly better than using GET, it does not solve the problem.
#How to guard against it?
- Check the
HTTP referrer. If it does not match your domain, something is wrong. However, this method can break legitimate requests, since some corporate proxies strip the referrer from all HTTP requests. Additionally, it is possible to forge a request and spoof the referrer, making this method unreliable. - Add a hidden field to the form. Generate a random token and include it as a hidden field. When the client submits the form, the server verifies that the hidden field value matches what it generated. Example:
<input id="a" name="a" type="hidden" value="hjkguyez721g45654gfd12cwx400huiyu" /> - similar in concept to a CAPTCHA. - Add a cookie. When the page is served, the server sends a cookie containing a token. When the client submits the form, it returns the cookie and the server verifies that its value matches what it generated.
With these techniques in place, you have everything you need to protect your websites from CSRF attacks.
Do you have a question or a suggestion about this post? Contact me!