SameSite cookie recipes  |  Articles  |  web.dev (2024)

SameSite cookie recipes | Articles | web.dev (1)

Rowan Merewood

Chrome,Firefox,Edge,and others are changing their default behavior in line with the IETFproposal,Incrementally Better Cookiesso that:

  • Cookies without a SameSite attribute are treated as SameSite=Lax,meaning the default behavior is to restrict cookies to first partycontexts only.
  • Cookies for cross-site usage must specify SameSite=None; Secure toenable inclusion in third party context.

If you haven't already done so, you should update the attributes for yourthird-party cookies so they won't be blocked in the future.

Browser Support

  • 51
  • 16
  • 60
  • 13

Source

Use cases for cross-site or third-party cookies

There are a number of common use cases and patterns where cookies need to besent in a third-party context. If you provide or depend on one of these usecases, make sure that either you or the provider are updating their cookies tokeep the service functioning correctly.

Content within an <iframe>

Content from a different site displayed in an <iframe> is in a third-partycontext. Standard use cases include:

  • Embedded content shared from other sites, such as videos, maps, code samples,and social posts.
  • Widgets from external services such as payments, calendars, booking, andreservation features.
  • Widgets such as social buttons or anti-fraud services that create less obvious<iframes>.

Cookies may be used here to, among other things, maintain session state, storegeneral preferences, enable statistics, or personalize content for users withexisting accounts.

SameSite cookie recipes | Articles | web.dev (2)

Because the web is inherently composable, <iframes> are also used to embedcontent viewed in a top-level or first-party context. Any cookies the sitedisplayed in the iframe uses are considered third-party cookies. If you'recreating sites that you want other sites to embed, and need cookies to make themwork, you also need to ensure those are marked for cross-site usage or that youcan fall back gracefully without them.

"Unsafe" requests across sites

"Unsafe" might sound concerning here, but it refers to any request that might beintended to change state. On the web, that's primarily POST requests. Cookiesmarked as SameSite=Lax are sent on safe top-level navigations, like clicking alink to go to a different site. However, something like a <form> submission toa different site using POST doesn't include cookies.

SameSite cookie recipes | Articles | web.dev (3)

This pattern is used for sites that can redirect the user out to a remoteservice to perform some operation before returning, for example, redirecting toa third-party identity provider. Before the user leaves the site, a cookie isset containing a single use token with the expectation that this token can bechecked on the returning request to mitigateCross Site Request Forgery (CSRF)attacks. If that returning request comes through POST, you'll need to mark thecookies as SameSite=None; Secure.

Remote resources

Any remote resource on a page, such as from <img> tags or <script> tags,might rely on cookies being sent with a request. Common use cases includetracking pixels and personalizing content.

This also applies to requests sent from your JavaScript using fetch orXMLHttpRequest. If fetch() is called with thecredentials: 'include' option,those requests are likely to include cookies.For XMLHttpRequest, expected cookies are usually indicated by awithCredentials valuefo true. Those cookies must be appropriately marked to be included incross-site requests.

Content within a WebView

A WebView in a platform-specific app is powered by a browser. Developers need totest whether the restrictions or issues that affect their apps also apply totheir app's WebViews.

Android also lets its platform-specific apps set cookies directly using theCookieManager API.As with cookies set using headers or JavaScript, consider includingSameSite=None; Secure if they're intended for cross-site use.

How to implement SameSite today

Mark any cookies that are only needed in a first-party context as SameSite=Laxor SameSite=Strict depending on your needs. If you don't mark these cookiesand instead rely on default browser behavior to handle them, they can behaveinconsistently across browsers and potentially trigger console warnings for eachcookie.

Set-Cookie: first_party_var=value; SameSite=Lax

Make sure to mark any cookies needed in a third-party context asSameSite=None; Secure. Both attributes are required. If you just specifyNone without Secure, the cookie will be rejected. To account for differencesin browser implementations, you might need to use some of the mitigatingstrategies described in Handle incompatible clients.

Set-Cookie: third_party_var=value; SameSite=None; Secure

Handle incompatible clients

Because these changes to include None and update default behavior are stillrelatively new, different browsers handle them in different ways. You can referto the updates page on chromium.orgfor a list of known issues, but this list might not be exhaustive.

One possible workaround is to set each cookie in both the new and the old style:

Set-cookie: 3pcookie=value; SameSite=None; SecureSet-cookie: 3pcookie-legacy=value; Secure

Browsers implementing the newer behavior set the cookie with the SameSitevalue. Browsers that don't implement the new behavior ignore that value and setthe 3pcookie-legacy cookie. When processing included cookies, your site shouldfirst check for the presence of the new style of cookie and, then fall back tothe legacy cookie if it can't find a new one.

The following example shows how to do this in Node.js, using theExpress framework and itscookie-parser middleware:

const express = require('express');const cp = require('cookie-parser');const app = express();app.use(cp());app.get('/set', (req, res) => { // Set the new style cookie res.cookie('3pcookie', 'value', { sameSite: 'none', secure: true }); // And set the same value in the legacy cookie res.cookie('3pcookie-legacy', 'value', { secure: true }); res.end();});app.get('/', (req, res) => { let cookieVal = null; if (req.cookies['3pcookie']) { // check the new style cookie first cookieVal = req.cookies['3pcookie']; } else if (req.cookies['3pcookie-legacy']) { // otherwise fall back to the legacy cookie cookieVal = req.cookies['3pcookie-legacy']; } res.end();});app.listen(process.env.PORT);

This approach requires you to do extra work setting redundant cookies and makingchanges at the point of both setting and reading the cookie. However, it shouldcover all browsers regardless of their behavior, and keep third-party cookiesfunctioning.

As an alternative, you can detect the client using the user agent string when aSet-Cookie header is sent. Refer to thelist of incompatible clients,and use an appropriate user agent detection library for your platform, forexample, the ua-parser-js libraryon Node.js. This approach only requires you to make one change, but user agentsniffing might not catch all affected users.

Support for SameSite=None in languages, libraries, and frameworks

The majority of languages and libraries support the SameSite attribute forcookies. However, because the addition of SameSite=None is still relativelyrecent, you might need to work around some standard behavior for now.These behaviors are documented in theSameSite examples repository on GitHub.

Getting help

Cookies are used everywhere on the web, and it's rare for any development teamto have complete knowledge of where their site sets and uses them, especiallyin cross-site use cases. When you encounter an issue, it might be the first timeanyone has encountered it, so don't hesitate to reach out:

SameSite cookie recipes  |  Articles  |  web.dev (2024)

References

Top Articles
Latest Posts
Article information

Author: Domingo Moore

Last Updated:

Views: 6135

Rating: 4.2 / 5 (53 voted)

Reviews: 84% of readers found this page helpful

Author information

Name: Domingo Moore

Birthday: 1997-05-20

Address: 6485 Kohler Route, Antonioton, VT 77375-0299

Phone: +3213869077934

Job: Sales Analyst

Hobby: Kayaking, Roller skating, Cabaret, Rugby, Homebrewing, Creative writing, amateur radio

Introduction: My name is Domingo Moore, I am a attractive, gorgeous, funny, jolly, spotless, nice, fantastic person who loves writing and wants to share my knowledge and understanding with you.