CSRF for Web Developer

What is CSRF

CSRF (Cross-Site Request Forgery) means an attacker sends malicious requests using the user’s identity.
Specifically, this attack exploits the browser’s default behavior of including Cookies with requests, using various methods to get the browser to send requests without the user’s knowledge to achieve malicious goals.

For example, if a user logs into website A and leaves sensitive information in the browser’s Cookie, then visits a malicious website that contains malicious request code, when triggered, it will cause the user to send a malicious forged request to website A from the designed malicious page B.

  • It can be clicking a link
<a href="http://bank.com/transfer.do?acct=MARIA&amount=100000">View my Pictures!</a>
  • It can be loading a hidden image
<img src="http://bank.com/transfer.do?acct=MARIA&amount=100000" width="0" height="0" border="0" />
  • It can be loading a hidden auto-submit form
<body onload="document.forms[0].submit()">
<form action="http://bank.com/transfer.do" method="POST">
<input type="hidden" name="acct" value="MARIA" />
<input type="hidden" name="amount" value="100000" />
<input type="submit" value="View my pictures" />
</form>
</body>

The concept is to trick the user into making requests to other websites through different methods.

Preventing CSRF

Preventing CSRF from the user’s perspective is indeed more difficult; most protection measures need to be implemented on the server side. On the client side, the best thing you can do is:

  1. Do not store any sensitive information in the browser; log out every time after using the website.
  2. Avoid entering suspicious websites from unknown sources.

The fundamental way to prevent CSRF is to “not trust requests that come from oneself.” You must add some verification mechanisms that require user interaction or information only the user knows to confirm the legitimacy of the request.

CSRF Token

The server can generate random CSRF Tokens for different users and compare them when receiving requests. Since CSRF Tokens are not stored in Cookies, cross-site pages cannot access them, thus confirming whether the user’s request is indeed from the user.

For example, automatically including a server-generated CSRF Token with form submissions, it is only a valid request when the CSRF Token matches:

<form action="http://bank.com/transfer.do" method="POST">
<input type="hidden" name="csrf-token" value="Generate CSRF Token Here..." />
<button type="submit">Submit</button>
</form>

Set the SameSite attribute for Cookies to restrict third-party websites from accessing them. This way, malicious forged requests cannot be sent through third-party sites. However, this approach relies on browser support, and you can check the details at samesite - caniuse🔗.

The SameSite Cookie attribute has three modes, allowing you to balance convenience and security:

  • Strict: Cookies are only sent when the visitor interacts directly with the same site.
  • Lax (default for most browsers): Allows “safe cross-site requests” (like GET links, form submits) but does not allow unsafe requests (like POST, PUT, DELETE) to carry Cookies.
  • None: Allows any cross-site requests to carry Cookies.
Set-Cookie: sessionId=abc123; Path=/; HttpOnly; Secure; SameSite=Lax

Conclusion

Regardless, one should never easily trust user requests to prevent CSRF. As users increasingly utilize browsers that prioritize Cookie access security, we can expect CSRF to be more effectively and simply prevented.

Further Reading