DEV Community

wennan xu
wennan xu

Posted on

SameSite cookies and CSRF explained

We might normally heard the terms of SameSite and CSRF, What are they on the earth, and what's the relationship between them?

What is HTTP cookies

A cookie (also known as a web cookie or browser cookie) is a small piece of data a server sends to a user's web browser. The browser may store cookies, create new cookies, modify existing ones, and send them back to the same server with later requests. Cookies enable web applications to store limited amounts of data and remember state information; by default the HTTP protocol is stateless.
Typically, the server will use the contents of HTTP cookies to determine whether different requests come from the same browser/user and then issue a personalized or generic response as appropriate.

  1. The user sends sign-in credentials to the server, for example via a form submission.
  2. If the credentials are correct, the server updates the UI to indicate that the user is signed in, and responds with a cookie containing a session ID that records their sign-in status on the browser.
  3. At a later time, the user moves to a different page on the same site. The browser sends the cookie containing the session ID along with the corresponding request to indicate that it still thinks the user is signed in.
  4. The server checks the session ID and, if it is still valid, sends the user a personalized version of the new page. If it is not valid, the session ID is deleted and the user is shown a generic version of the page (or perhaps shown an "access denied" message and asked to sign in again).

Image description

What is a site in the context of SameSite cookies?

Firstly we need to understand what is same site and what is same origin.

Image description

Request from Request to Same-site? Same-origin?
https://example.com https://example.com Yes Yes
https://app.example.com https://intranet.example.com Yes No: mismatched domain name
https://example.com https://example.com:8080 Yes No: mismatched port
https://example.com https://example.co.uk No: mismatched eTLD No: mismatched domain name
https://example.com http://example.com No: mismatched scheme No: mismatched scheme

How does SameSite work?

All major browsers currently support the following SameSite restriction levels:

  • Strict:If a cookie is set with the SameSite=Strict attribute, browsers will not send it in any cross-site requests. This is recommended when setting cookies that enable the bearer to modify data or perform other sensitive actions, such as accessing specific pages that are only available to authenticated users.

Although this is the most secure option, it can negatively impact the user experience in cases where cross-site functionality is desirable.

  • Lax:Lax SameSite restrictions mean that browsers will send the cookie in cross-site requests, but only if both of the following conditions are met:
    • The request uses the GET method.
    • The request resulted from a top-level navigation by the user, such as clicking on a link.
<p>Look at this amazing cat!</p>
<img src="https://blog.example/blog/img/amazing-cat.png" />
<p>Read the <a href="https://blog.example/blog/cat.html">article</a>.</p>
Enter fullscreen mode Exit fullscreen mode

With a cookie set to Lax as follows: Set-Cookie: promo_shown=1; SameSite=Lax
When the browser requests amazing-cat.png for the other person's blog, your site doesn't send the cookie. However, when the reader follows the link to cat.html on your site, that request does include the cookie.

We recommend using SameSite in this way, setting cookies that affect website display to Lax, and cookies related to user actions to Strict.

  • None:If a cookie is set with the SameSite=None attribute, this effectively disables SameSite restrictions altogether, regardless of the browser. As a result, browsers will send this cookie in all requests to the site that issued it, even those that were triggered by completely unrelated third-party sites. When you create cross-site cookies using SameSite=None, you must also set them to Secure for the browser to accept them: Set-Cookie: widget_session=abc123; SameSite=None; Secure

Bypassing SameSite Lax restrictions using GET requests

As long as the request involves a top-level navigation, the browser will still include the victim's session cookie. The following is one of the simplest approaches to launching such an attack:

<script>
    document.location = 'https://vulnerable-website.com/account/transfer-payment?recipient=hacker&amount=1000000';
</script>
Enter fullscreen mode Exit fullscreen mode

Even if an ordinary GET request isn't allowed, some frameworks provide ways of overriding the method specified in the request line. For example, Symfony supports the _method parameter in forms, which takes precedence over the normal method for routing purposes:

<form action="https://vulnerable-website.com/account/transfer-payment" method="POST">
    <input type="hidden" name="_method" value="GET">
    <input type="hidden" name="recipient" value="hacker">
    <input type="hidden" name="amount" value="1000000">
</form>
Enter fullscreen mode Exit fullscreen mode

see we can put <input type="hidden" name="_method" value="GET"> in forms to override the override the original POST request.

Bypassing SameSite restrictions using on-site gadgets

One possible gadget is a client-side redirect that dynamically constructs the redirection target using attacker-controllable input like URL parameters. For some examples, see our materials on DOM-based open redirection.
DOM-based open-redirection vulnerabilities arise when a script writes attacker-controllable data into a sink that can trigger cross-domain navigation. For example, the following code is vulnerable due to the unsafe way it handles the location.hash property:

let url = /https?:\/\/.+/.exec(location.hash);
if (url) {
  location = url[0];
}
Enter fullscreen mode Exit fullscreen mode

An attacker may be able to use this vulnerability to construct a URL that, if visited by another user, will cause a redirection to an arbitrary external domain.
As far as browsers are concerned, these client-side redirects aren't really redirects at all; the resulting request is just treated as an ordinary, standalone request. Most importantly, this is a same-site request and, as such, will include all cookies related to the site, regardless of any restrictions that are in place.
How to prevent DOM-based open-redirection vulnerabilities, you should avoid dynamically setting redirection targets using data that originated from any untrusted source.

Bypassing SameSite Lax restrictions with newly issued cookies

Cookies with Lax SameSite restrictions aren't normally sent in any cross-site POST requests, but there are some exceptions.

As mentioned earlier, if a website doesn't include a SameSite attribute when setting a cookie, Chrome automatically applies Lax restrictions by default. However, to avoid breaking single sign-on (SSO) mechanisms, it doesn't actually enforce these restrictions for the first 120 seconds on top-level POST requests. As a result, there is a two-minute window in which users may be susceptible to cross-site attacks.

Note
This two-minute window does not apply to cookies that were explicitly set with the SameSite=Lax attribute.
Enter fullscreen mode Exit fullscreen mode

References:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions
https://web.dev/articles/samesite-cookies-explained

Top comments (0)