CSRF (Cross Site Request Forgery Attack)
Definition
Happen when we explicitly set the Cookies's SameSite
attribute None
Example
- User logged into a banking website which does not set
SameSite=Strict
orSameSite=Lax
.- Therefore, the user's cookies is accessible from any sites.
- Attacker create a malformed website and trick user to access the website.
- The website automatically
submit
a banking transfer request to the bank using the user previously logged in cookies:
- The website automatically
- The user lost money
Solution
CSRF Token
Basic idea
We attach an unique token
for each form we send to user. This is included by default in ASP.NET Razer framework.
In this case, when the user send the form we can then attach the csrfToken
inside the form, for example:
It would be impossible for the attacker to guess the value of csrfToken
beforehand, therefore will prevent CSRF.
Synchronised CSRF Token
Given the idea above, it's important to compare the CSRF token: the one from the client side and the one the server side has.
As a result, the server needs to store a CSRF token for each user session.
- We want to store per session because sometimes when user click the
Back
button, storing per request will make the cookie invalid. - The CSRF token will be unique per session.
[!note]
For synchronised CSRF token, the token should not be transmitted using cookies. This is to minimise the vulnerability from cookies
We can transmit the token to client using a response payload as part of the respond like HTML
or JSON
.
For client to transmit back to the server we can use hidden form or request header.
- It's recommended to use request header because it subject to same-origin policy
Double submit cookie
The synchronised CSRF token approach requires us to maintain the state of the token on the server. If we prefer a stateless implementation to prevent CSRF, we can implement the double submit cookie.
The idea is that we provide the CSRF token from server side to the client using HttpOnly Cookie — which cannot be forged by client side.
We then compare if the CSRF sent in the cookie is the same as the CSRF sent by the client (via hidden input or request).
Since the CSRF sent using HttpOnly is not forgable and not seeable from client, it's impossible for the attacker to forge this CSRF token.
Signed double submit cookie
However, a possible vulnerability is if the attacker using man-in-the middle attack, which then modify the HttpOnly Cookie in a way that the CSRF in the cookie is the same as the CSRF in the payload given by user
See: Bypassing CSRF Protections: A Double Defeat of the Double-Submit Cookie Pattern (owasp.org)
To address the problem above, we can sign our cookie with a secret key. As a result, it's impossible for attacker to know our secret key to create a fake encrypted CSRF.
SameSite Cookie
We can set the SameSite=Strict
or SameSite=Lax
in Cookies header. This will prevent if the script triggered a POST
request on behalf of the user.
As a result, when the attacker try to forge the cookie, it wouldn't be able to because it is not from the same site.