Why will a browser refuse a Set-Cookie with `Domain=co.uk` from a page on `shop.example.co.uk`, and why is there no way for example.com to set a cookie that another-site.com will send?
answer
- PSL blocks Domain= on co.uk, com, github.io
- narrowest allowed = registrable domain (eTLD+1)
- stops supercookies + cross-site fixation
- Domain must domain-match the setting host
- cross-domain SSO = redirect + token, never shared cookie
basics
~20 sBrowsers use the Public Suffix List to block cookies scoped to a registry-controlled suffix like co.uk, which would otherwise leak across unrelated sites. And a cookie's Domain must domain-match the setting host, so cross-registrable-domain cookies are impossible by construction.
solid answer
~50 sTwo separate rules. **Public Suffix List.** A cookie's `Domain` widens it to all subdomains. If `shop.example.co.uk` could set `Domain=co.uk`, every UK site would receive and could overwrite that cookie — a supercookie and a session-fixation vector. Browsers therefore consult the Public Suffix List (a community-maintained list of registry-like suffixes: `com`, `co.uk`, `github.io`, `s3.amazonaws.com`, many cloud and hosting domains) and reject a `Domain` equal to a public suffix. The narrowest allowed scope is one label below — the *registrable domain*, `example.co.uk`. **Domain-match rule.** The browser accepts `Domain=X` only if the request host is X or a subdomain of X. `example.com` can never name `another-site.com`, so there is no primitive for cross-site cookie sharing at all. Consequences: apps on shared hosting suffixes (`*.github.io`, `*.pages.dev`) cannot share cookies with siblings — which is the point — and cross-domain SSO must use redirects through the identity provider's origin rather than a shared cookie.
code
http · 4 linesSet-Cookie: a=1; Domain=example.co.uk (accepted)
Set-Cookie: b=1; Domain=shop.example.co.uk (accepted)
Set-Cookie: c=1; Domain=co.uk (rejected: public suffix)
Set-Cookie: d=1; Domain=another.co.uk (rejected: no domain match)go deeper
Know that browsers refuse cookies scoped to things like com or co.uk, and that cookies never cross to unrelated sites.
Name the Public Suffix List and the registrable-domain/eTLD+1 concept, and state the domain-match rule that blocks sideways scoping.
Explain the supercookie and fixation attacks the rule prevents, the PRIVATE-section obligation for platforms delegating subdomains, and the redirect-based SSO pattern that replaces cookie sharing.
Treat eTLD+1 as the architectural unit of trust: how subdomain delegation, tenant isolation, PSL lead time, and token-based federation shape the platform's domain strategy.
## The supercookie problem Cookie scope has exactly one widening knob: `Domain`. Setting `Domain=example.com` from `app.example.com` makes the cookie visible to, and writable by, everything under `example.com`. That is fine within one owner's namespace — the owner controls all the subdomains. Now apply the same rule one level up. If `shop.example.co.uk` could set `Domain=co.uk`, the cookie would be sent to `bank.co.uk` and every unrelated UK business under that suffix. Two attacks follow immediately: - **Tracking supercookie**: one site plants an identifier that every other site under the suffix then transmits, defeating the site-based partitioning cookies are supposed to have. - **Session fixation across sites**: an attacker's site writes `session=known-value; Domain=co.uk`; a victim later visits an unrelated site under that suffix whose server trusts an incoming session cookie, and the attacker knows the session id. The naive rule "you cannot set a cookie on a top-level domain" does not work, because "top level" is not one label. `com` is a registry, but so are `co.uk`, `com.au` and `pvt.k12.ma.us`. Worse, plenty of *private* suffixes behave the same way: `github.io`, `pages.dev`, `netlify.app`, `s3.amazonaws.com`, `blogspot.com` — all of them hand out subdomains to mutually untrusting parties. ## The Public Suffix List The answer is data, not an algorithm: the **Public Suffix List** (PSL), a community-maintained file with an ICANN section (registry suffixes) and a PRIVATE section (companies that delegate subdomains to third parties). Browsers embed it and refuse any `Set-Cookie` whose `Domain` value is exactly a public suffix. The smallest scope you can name is therefore the **registrable domain** — the public suffix plus one label: `example.co.uk`, `myproject.github.io`, `mybucket.s3.amazonaws.com`. This same notion, often called eTLD+1 or "site", is reused far beyond cookies: it defines what "same-site" means for `SameSite`, cookie partitioning, and various browser security UIs. Operationally this bites in two ways. First, if you host on a shared suffix, sibling projects genuinely cannot share cookies — by design. Second, if you *are* a platform handing out subdomains to customers (`*.tenants.yourapp.com`), you should submit your suffix to the PSL PRIVATE section; until you do, one tenant can set `Domain=tenants.yourapp.com` and shadow cookies for every other tenant. Inclusion is not instant — it requires a pull request and browser releases to pick it up — so treat it as a lead-time item, not a launch-day fix, and do not let tenant sessions depend on it. ## Why cross-site cookies simply do not exist Separately from the PSL, the browser applies the **domain-match** rule when storing a cookie: the `Domain` value is accepted only if the request host equals it or is a subdomain of it. So `example.com` may set `Domain=example.com` (widening down) but can never name `another-site.com` (sideways). There is no mechanism, no header, no permission grant that lets one registrable domain write a cookie another registrable domain will send. This is why so much of the web's architecture looks the way it does: - **Third-party cookies** were never cross-domain sharing. They are cookies set by the *tracker's own domain* on responses to subresource requests embedded in many sites — the tracker's domain each time. Browser work on blocking and partitioning them changes that, but it never introduced sharing. - **Cross-domain SSO** cannot work by copying a cookie. It works by redirecting the browser to the identity provider's origin, where the IdP's own cookie is in scope, and returning a token in the URL that the relying party exchanges for its own host-scoped cookie. Each domain ends up with its own cookie. - **CORS does not change cookies.** `Access-Control-Allow-Credentials` lets a cross-origin request *carry* cookies that already belong to the target host and lets the response *set* cookies for the target host; it never lets one site read or write another site's jar. The practical takeaway for design: treat the registrable domain as your cookie's maximum reach, put anything that must cross that line into a token flow, and if you delegate subdomains to parties you do not control, get on the PSL and prefer `__Host-` host-only cookies so a hostile sibling cannot shadow you.
- You run a SaaS that gives each customer a subdomain under tenants.yourapp.com. What cookie risk does that create and what do you do about it?Any tenant page can set a cookie with Domain=tenants.yourapp.com, so it is readable and overwritable by every other tenant — cross-tenant leakage and session fixation. Submit tenants.yourapp.com to the Public Suffix List PRIVATE section so browsers refuse that scope, and in the meantime keep tenant session cookies host-only with the __Host- prefix so a sibling cannot shadow them.
- If cookies cannot cross registrable domains, how does single sign-on work across example.com and example-partner.com?By redirect, not by sharing. The browser is sent to the identity provider's own origin, where the IdP's session cookie is in scope; the IdP redirects back with a short-lived code or token in the URL, and each relying party exchanges it for a session cookie scoped to its own host. Every domain still ends up with its own separate cookie.
You can put a note in your own building's mailroom, but not in the postcode's central sorting office where every building in the district would collect it.
saying these in an interview costs you the question
- Thinking the rule is just 'no cookies on TLDs', missing multi-label and private suffixes like co.uk and github.io
- Believing CORS with credentials lets one site set cookies for another site
- Describing third-party cookies as cross-domain cookie sharing
- Assuming Public Suffix List inclusion takes effect immediately after the pull request
- Planning cross-domain SSO around copying a session cookie between domains