CSRF Tokens and SameSite Cookies

Primary Defense: CSRF Tokens

A CSRF token is a unique, secret, unpredictable value that is generated by the server-side application and transmitted to the client in such a way that it is included in a subsequent HTTP request made by the client. When the later request is made, the server-side application validates that the request includes the expected token and rejects the request if the token is missing or invalid.

CSRF tokens can prevent CSRF attacks by making it impossible for an attacker to construct a fully valid HTTP request suitable for feeding to a victim user. Since the attacker cannot determine or predict the value of a user's CSRF token, they cannot construct a request with all the parameters that are necessary for the application to honor the request.

CSRF tokens should contain significant entropy and be strongly unpredictable, with the same properties as session tokens in general. You should use a CSPRNG, seeded with the timestamp when it was created plus a static secret.

CSRF tokens should be treated as secrets and handled in a secure manner throughout their lifecycle. An approach that is normally effective is to transmit the token to the client within a hidden field of an HTML form that is submitted using the POST method. The token will then be included as a request parameter when the form is submitted:

<input type="hidden" name="csrf-token" value="CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz" />

Why CSRF tokens prevent CSRF?

  • CSRF tokens are added to the HTTP request by the web app.

  • Cookies are added to the HTTP request by the browser.

  • CSRF vulnerabilities exist because the browser adds cookies to HTTP requests automatically.

  • The browser does not know the value of the CSRF tokens, hence CSRF tokens prevent CSRF.

Additional Defense: SameSite Cookies

The SameSite attribute can be used to control whether and how cookies are submitted in cross-site requests. By setting the attribute on session cookies, an application can prevent the default browser behavior of automatically adding cookies to requests regardless of where they originate.

The SameSite attribute is added to the Set-Cookie response header when the server issues a cookie, and the attribute can be given two values, Strict or Lax.

SameSite=Strict (Too Defensive)

Set-Cookie: SessionId=sYMnfCUrAlmqVVZn9dqevxyFpKZt30NN; SameSite=Strict;

If the SameSite attribute is set to Strict, then the browser will not include the cookie in any requests that originate from another site. This is the most defensive option, but it can impair the user experience, because if a logged-in user follows a third-party link to a site, then they will appear not to be logged in, and will need to log in again before interacting with the site in the normal way.

SameSite=Lax (Use This)

Set-Cookie: SessionId=sYMnfCUrAlmqVVZn9dqevxyFpKZt30NN; SameSite=Lax;

If the SameSite attribute is set to Lax, then the browser will include the cookie in requests that originate from another site but only if two conditions are met:

  • The request uses the GET method. Requests with other methods, such as POST, will not include the cookie.

  • The request resulted from a top-level navigation by the user, such as clicking a link. Other requests, such as those initiated by scripts, will not include the cookie.

Using SameSite cookies in Lax mode does then provide a partial defense against CSRF attacks, because user actions that are targets for CSRF attacks are often implemented using the POST method.

Use CSRF tokens + SameSite cookies together for an additional layer of defense.

Reference

Last updated