learning-website-framework1-1 Exercise 3: Same Origin, Same Site or Cross-Site? ============================================================================== Save as classify.py and run: python classify.py from urllib.parse import urlsplit DEFAULT_PORTS = {"http": 80, "https": 443} def origin(url): u = urlsplit(url) port = u.port or DEFAULT_PORTS[u.scheme] return (u.scheme, u.hostname, port) def registrable_domain(host): # Simplification: last two labels. Real code must use the Public Suffix # List, because "example.co.uk" has THREE labels in its registrable part. return ".".join(host.split(".")[-2:]) def same_site(a, b): sa, ha, _ = origin(a) sb, hb, _ = origin(b) return sa == sb and registrable_domain(ha) == registrable_domain(hb) def classify(a, b): if origin(a) == origin(b): return "same-origin" if same_site(a, b): return "same-site, cross-origin" return "cross-site" pairs = [ ("https://osztromok.com/", "https://osztromok.com/japan/"), ("https://languages.osztromok.com/", "https://osztromok.com/"), ("https://languages.osztromok.com/", "https://webdevelopment.osztromok.com/"), ("https://languages.osztromok.com/", "http://languages.osztromok.com/"), ("https://languages.osztromok.com/", "https://languages.osztromok.com:8443/"), ("https://languages.osztromok.com/", "https://example.org/"), ] for a, b in pairs: print(f"{classify(a, b):<24} {a} vs {b}") Output (checked by running it): same-origin https://osztromok.com/ vs https://osztromok.com/japan/ same-site, cross-origin https://languages.osztromok.com/ vs https://osztromok.com/ same-site, cross-origin https://languages.osztromok.com/ vs https://webdevelopment.osztromok.com/ cross-site https://languages.osztromok.com/ vs http://languages.osztromok.com/ same-site, cross-origin https://languages.osztromok.com/ vs https://languages.osztromok.com:8443/ cross-site https://languages.osztromok.com/ vs https://example.org/ Reading the results ------------------- - Pages within one site (path split) are same-origin: they share cookies, localStorage and can fetch each other freely. - Subdomains are same-site but cross-origin: cookies can be shared if set with a Domain attribute for the parent domain, but localStorage is separate and a fetch from one subdomain to another needs CORS headers. - The http versus https pair comes out cross-site because this script (like modern browsers' "schemeful same-site" rule) requires the same scheme. - A different port is a different origin but still the same site. WHY THIS WORKS AS AN ANSWER --------------------------- Origin is scheme + host + port, and it governs things like localStorage and cross-origin fetch. Site is scheme + registrable domain, and it governs things like SameSite cookies. A subdomain split turns what was one origin into several origins that are still the same site. That is why a cookie set on the parent domain can be shared across the sites while localStorage and unauthenticated fetches cannot. The simplification in registrable_domain() is the standard trap: always use the Public Suffix List in real code.