Definition
SameSite Cookie
The
SameSiteattribute of an HTTP cookie determines whether the cookie is attached to cross-site requests — requests where the site that initiates the request differs from the site the cookie belongs to. It has four possible values:
Value Behaviour Noneattach to cross-site requests; Securemust be enabledLaxattach only to top-level cross-site navigations using a safe method ( GET)Strictnever attach to cross-site requests (unspecified) usually defaults to Laxafter 2 minutesA request from
example.comthat embeds an image frompics.comcrosses sites; whether the cookie onpics.comis sent topics.comalong with that image fetch is exactly whatSameSitedecides.
Site Test
Obs
The decision is a two-place comparison, not “the from site alone”. A cookie lives in the jar of some target site
to; a request originates from a page on sitefrom. The browser asks: isfromthe same site asto?
from == to(same site) ⇒ the request is same-site ⇒ the cookie is attached regardless ofSameSitevalue (the attribute only governs cross-site requests).from != to(different site) ⇒ the request is cross-site ⇒ the value decides:Noneattaches,Strictomits,Laxattaches only for a top-level safe-method navigation, unspecified ≈Laxafter 2 minutes.For one fixed cookie the target site
tonever changes, so across the lecture examples only the initiator (b.com,foo.bar.a.com,window.open, …) varies — which is why it looks like only the from matters. The test is genuinelysameSite(from, to).
Obs
The “same-site” test that
SameSiteuses is scheme-aware: for cookie purposes,http://a.comandhttps://a.comare different sites even though they share a registrable domain. This is a stricter notion of same-site than the site boundary used by CORS or CSP.
Top-Level Safe-Method Navigation
The two ingredients in
Lax's rule
Laxattaches cookies only on a cross-site request that is both a top-level navigation and uses a safe method. Each qualifier rules out a different way a page can reach a cross-origin resource.
- Top-level navigation — the request replaces what is shown as the page itself in a browser tab: clicking a link (
<a href>), submitting a form withtarget=_self, orwindow.open. A request contained inside the page — an<iframe>, an embedded<img>/<script>/<link>, afetch/XHR call — does not count, because the viewer is still on the initiating page and never visibly navigated to the cross-site one.- Safe method — a method that is read-only and side-effect-free by convention; in practice
GET(andHEAD). APOST,PUT,DELETE, or other state-changing method does not count even when the navigation itself is top-level, becauseLaxonly relaxes for navigations that look like a user following a link.So a
Laxcookie is attached exactly when a cross-site visit is something a user would see as visiting the target site and uses a read-only verb. Aniframeembedding the same URL is neither top-level nor — forPOST— safe, hences3(iframe) and the Lax+POST hack both drop the cookie.
Decision Diagram
Intuition
The browser walks the tree below for each cookie in the jar of the requested site. The first question is the two-place same-site test; only if it fails — i.e. the request is cross-site — does the
SameSitevalue get consulted.The same-site branch never consults the value, which is the part that gets forgotten: a same-site
POSTis sent underStrict, becauseStrictonly governs cross-site requests. The cookie-specific scheme rule can even flip a request that looks same-site (shared registrable domain) into cross-site, ass8in the example shows — it falls through to the cross-site branch and is then stopped byStrict.
Lax+POST Hack
Lax+POST 2-minute hack
Cookies whose
SameSiteis left unspecified fall back to plain cross-site top-levelPOSTbehaviour for the first 2 minutes after they are set — an exception added for single sign-on flows. During that window the cookie behaves closer toNone, so unspecified is not the same as safe. The behaviour is also browser-dependent.
Example
Which cookies get sent, by request type and
SameSiteA victim holds four cookies on
https://a.com(s1–s4), each set with a differentSameSite. From a separate page, the victim triggers an action that requestsa.com:
s1; Secure; SameSite=Lax— sent ✅
- the victim clicks a link to
https://a.com:8443fromhttp://b.com, a top-levelGETLaxallows top-level cross-site navigations using a safe method, and a link click qualifiess2; HttpOnly; SameSite=Strict— sent ✅
- the victim submits a
POSTform tohttps://a.comfromhttps://foo.bar.a.comStrictblocks only cross-site requests, andfoo.bar.a.comshares the registrable domaina.comwitha.com— thePOSTis same-site, soStrictpermits its3; SameSite=Lax— not sent ❌
b.comembeds an<iframe src=https://a.com/user>- an
iframeis not a top-level navigation, andLaxprotects embedded subresources — so the cookie stays in the jars4; SameSite=Lax— sent ✅
b.comopenswindow.open('https://a.com'), a top-level navigationLaxallows top-level cross-site navigations, andwindow.openqualifies
SameSite=NonerequiresSecure, and the protocol matters for cookiesA second batch illustrates two traps:
s5; SameSite=None; HttpOnly(noSecure) — never stored ❌
- the victim clicks a link to
https://a.comfromhttps://b.comSameSite=NonemandatesSecure; the missingSecuremakes the wholeSet-Cookieinvalid, so the browser drops the cookie before any request is mades6; Domain=a.com; SameSite=Strict— sent ✅
- the victim navigates directly to
https://www.a.com- a direct navigation is same-site, so
Strictallows its7; Domain=a.com; SameSite=Strict— sent ✅
- the victim submits a
POSTform tohttps://login.a.comfromhttps://www.a.com- despite the
POST, the request is same-site (bad.a.comsetting andwww.a.com/login.a.comall share registrable domaina.com, same scheme), soStrictallows its8; Domain=a.com; SameSite=Strict— not sent ❌
- the victim clicks a link to
https://a.comfromhttp://bad.a.com- the cookie was set over
http://bybad.a.comand is read overhttps://toa.com; for cookies the scheme is part of the same-site test, sohttp://bad.a.comandhttps://a.comare different sites for cookie purposes despite the shared registrable domainStricttherefore blockss8, even thoughbad.a.comanda.comlook like the same site under the site definition used by CORS or CSP