Hostname vs. Domain
Hostname, domain, registrable domain (eTLD+1), site and origin are different things, and browser security depends on the difference. Compare real URL pairs and see which checks treat them as the same.
🎯 What you'll learn
- Hostname vs domain vs registrable domain
- The Public Suffix List problem
- Same-site is defined by eTLD+1
- Cookie Domain scoping; origin is stricter than site
📚 Before you start
This topic assumes the Browser Request Lifecycle and CORS topics from this group — it fills in a precise vocabulary gap those topics lean on but don't formally define: what exactly counts as "the same site" for cookies and origin checks.
1The Two Words People Use Interchangeably (and Shouldn't)
- Hostname: the exact name of one specific machine or service, e.g.
api.example.com,www.example.com,checkout.shop.example.com. It's the literal string betweenhttps://and the next/or:in a URL. - Domain: the registrable unit — the name someone actually bought from a registrar, e.g.
example.com. A domain can host any number of distinct hostnames underneath it (www.example.com,api.example.com,mail.example.comare all different hostnames, all part of the same domain).
https://checkout.shop.example.com/cart
└──────────┬──────────┘
hostname
example.com
└────┬────┘
domainEvery hostname belongs to exactly one domain (by construction — it's built by prepending labels to the domain), but a domain can have unlimited hostnames built on top of it.
2Why "example.com" Alone Isn't Enough — the Public Suffix Problem
Naively, "domain = strip subdomains down to two labels" (a.b.example.com -> example.com) breaks immediately for domains like example.co.uk or example.github.io. .co.uk and .github.io are themselves NOT things anyone can register a full domain under directly in the "example.com" sense — they're public suffixes: registries where unrelated third parties independently register names (anyone can get <anything>.github.io, just like anyone can get <anything>.com).
alice.github.io <- Alice's independent site
bob.github.io <- Bob's independent site, UNRELATED to Alice'sTreating github.io as "the domain" here would be wrong — alice.github.io and bob.github.io are, for security purposes, as unrelated as alice.com and bob.com. The actual registrable unit is one label deeper: alice.github.io and bob.github.io respectively.
Browsers resolve this with the Public Suffix List (PSL) — a maintained, crowd-sourced list of every known suffix under which the public can register names (.com, .co.uk, .github.io, thousands of entries). The registrable domain is then defined precisely as:
eTLD+1 ("effective TLD, plus one label"): take the longest matching public suffix from the PSL for a given hostname, then include exactly one more label to its left.
hostname: checkout.shop.example.com
matching PSL suffix: com (eTLD)
eTLD+1 (the domain): example.comhostname: alice.github.io
matching PSL suffix: github.io (eTLD — a multi-label public suffix)
eTLD+1 (the domain): alice.github.io3"Same-Site" Is Defined in Terms of eTLD+1, Not Hostname
This is the concrete payoff for the rest of this group's topics. When the CORS topic and the CSRF topic talk about "same-site" (as distinct from "same-origin"), they mean same eTLD+1 — not same hostname:
https://app.example.com and https://api.example.com
-> DIFFERENT hostnames, DIFFERENT origins, but SAME SITE (both eTLD+1 = example.com)
https://alice.github.io and https://bob.github.io
-> DIFFERENT hostnames, and because github.io is a public suffix, DIFFERENT SITES too
(eTLD+1 differs: alice.github.io vs bob.github.io)SameSite=Lax/Strict cookies (CSRF topic, §4) are scoped by this same-site definition, not by hostname or full origin — which is precisely why a cookie set by app.example.com can be shared with api.example.com (same site) via an explicit Domain=example.com attribute, but two unrelated tenants both living under *.github.io can never accidentally share a SameSite cookie with each other, even if one tenant's page tries to set Domain=github.io (browsers reject setting a cookie's Domain to a public suffix outright, for exactly this reason).
4Cookie Scoping: Domain Attribute Rides on This Too
When a server sets a cookie, the (optional) Domain attribute controls which hostnames receive it:
Set-Cookie: session=abc123; Domain=example.com; Path=/- No
Domainattribute at all: the cookie is scoped to the exact hostname that set it (host-only cookie) —app.example.comsets it, onlyapp.example.comgets it back, notapi.example.com. Domain=example.com: the cookie is shared acrossexample.comand every subdomain of it (app.example.com,api.example.com,anything.example.com) — becauseexample.comis a legitimate registrable domain the site actually controls end-to-end.- Attempting
Domain=github.io(a public suffix): browsers refuse to set this. If they didn't,alice.github.iocould set a cookie thatbob.github.io— a completely unrelated party — would also receive, since both share that suffix. The PSL is exactly what lets the browser recognize and block this.
5Origin Is Stricter Than Site — Don't Conflate the Two
It's worth being precise that "same-site" (this topic) and "same-origin" (the CORS topic's unit) are different, nested concepts:
same-origin => same scheme + same hostname + same port (strictest)
same-site => same eTLD+1 (looser — ignores
subdomain, scheme,
and port entirely)https://app.example.com and https://api.example.com are same-site but NOT same-origin. https://example.com and http://example.com are same-site (identical eTLD+1) but NOT same-origin (different scheme). CORS decisions use same-origin; SameSite cookie behavior uses same-site — mixing the two up is a common source of confusion when debugging why a cookie is present but a CORS request still fails, or vice versa.
⚠️ Common Pitfalls
- Assuming "domain = strip to the last two labels." Breaks for any domain under a multi-label public suffix (
.co.uk,.github.io,.com.au, and thousands more) — always resolve against the actual Public Suffix List, never a fixed label count. - Conflating "same-site" with "same-origin." They answer different questions and are used by different mechanisms (
SameSitecookies vs. CORS/SOP) — same-site is a strict superset of same-origin. - Trying to set a cookie's
Domainto a public suffix, expecting it to "just work" across all hostnames under that suffix — browsers block this specifically because the PSL identifies it as unsafe (it would leak the cookie to unrelated third parties on the same suffix). - Forgetting that a host-only cookie (no
Domainattribute) does NOT get shared with subdomains — a very common source of "why isn't my session cookie visible onapi.example.comwhen it was set onapp.example.com" bugs; the fix is an explicitDomain=example.com, not assuming it's automatic. - Treating
www.example.comandexample.comas automatically interchangeable. They're different hostnames on the same domain/site — a cookie or CORS rule scoped to one does not automatically apply to the other unless explicitly configured to.
📋 Quick Reference
hostname = the exact machine/service name, e.g. api.example.com
domain = the registrable unit, e.g. example.com (unlimited hostnames can sit under it)
eTLD+1 = "public suffix from the PSL, plus one label" — the precise definition of "domain"
same-site = same eTLD+1 (ignores subdomain, scheme, port)
same-origin = same scheme + hostname + port (strict; used by CORS/SOP)
Cookie Domain attribute:
(unset) -> host-only, exact hostname that set it, no subdomain sharing
Domain=example.com -> shared across example.com and ALL its subdomains
Domain=<public suffix> -> browsers REFUSE (PSL prevents leaking across unrelated tenants)🧠 Key takeaways
- Hostname = full name (app.example.com); registrable domain / eTLD+1 = example.com.
- The Public Suffix List knows that co.uk and github.io are suffixes, not domains.
- Site = scheme + eTLD+1 (SameSite cookies); origin = scheme + host + port (CORS, storage).
- Cookie
Domain=widens scope to subdomains; omit it (or use__Host-) to stay host-only.
🎤 Interview Q&A
Q1What's the difference between a domain, a hostname and an FQDN?core▾
A domain is a name in the DNS hierarchy (example.com). A hostname labels a specific host (api in api.example.com). An FQDN is the complete name to the root (api.example.com.).
- What's a TLD? The top-level label like
.comor.uk.
Q2What's a registrable domain (eTLD+1) and why does it matter?core▾
The public suffix plus one label: example.co.uk (since co.uk is a public suffix). Browsers use it to decide what counts as 'same-site' for cookies and SameSite rules, via the Public Suffix List.
- Same-site vs same-origin? Same-site compares eTLD+1 (ignoring subdomains and ports); same-origin compares scheme, host and port exactly.
Q3What are the security implications of subdomains?senior▾
Cookies set with Domain=example.com are shared with all subdomains, so a compromised or user-controlled subdomain can read or overwrite them. Isolate user content on a separate registrable domain (e.g. usercontent.com).
- Why do GitHub Pages use github.io? To isolate user content from github.com cookies.
Q4How do wildcard certificates and DNS records work?core▾
*.example.com matches one level of subdomain (api.example.com, not a.b.example.com or example.com). Wildcards are convenient but widen the blast radius if the key leaks.
- Alternative? Per-host certificates automated with ACME/Let's Encrypt.
Q5What's the difference between a domain and a URL?core▾
A URL includes scheme, host (domain), port, path, query and fragment: https://api.example.com:443/v1/users?id=1#top. The domain is only part of it.
- Is the fragment sent to the server? No; it stays in the browser.
🛠️ Practice exercises
Each exercise is a file in this topic folder. Code exercises are self-checking: run them and make the checks pass.
✅ Check yourself
Answer the questions — feedback is instant.