Hacker DirectoryHacker Directory

WEB / WEB-06.02

Domain, site, and origin

Distinguish hostname, registrable domain, schemeful site, and origin for the same URL pair; separate browser boundaries from application permission.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Subdomain

  1. Pair selected

    The base https://app.example.com/catalog will be compared with https://api.example.com/catalog. The URL pair is ready; origin and site results are not yet computed.

    URL pair
    https://api.example.com/catalog
    Boundary calculation
    Origins: pending
    Result ledger
    Result: pending
  2. Origin tuples are separated

    The changed tuple component is hostname app.example.com → api.example.com. This HTTP(S) origin comparison gives same-origin=false; retaining path /catalog does not remove the changed component.

    URL pair
    https://api.example.com/catalog
    Boundary calculation
    Origin: https://api.example.com
    Result ledger
    Same-origin: false
  3. Site is computed separately

    The selected-domain fixture uses scheme and registrable domain, excluding port.

    URL pair
    https://api.example.com/catalog
    Boundary calculation
    Site: https://example.com
    Result ledger
    Same-site: true
  4. Both results are retained

    Classification is not access permission or network success.

    URL pair
    https://api.example.com/catalog
    Boundary calculation
    Local calculation complete
    Result ledger
    Same-origin: false; same-site: true

Port 8443

  1. Pair selected

    The base https://app.example.com/catalog will be compared with https://app.example.com:8443/catalog. The URL pair is ready; origin and site results are not yet computed.

    URL pair
    https://app.example.com:8443/catalog
    Boundary calculation
    Origins: pending
    Result ledger
    Result: pending
  2. Origin tuples are separated

    The changed tuple component is effective port 443 → 8443. This HTTP(S) origin comparison gives same-origin=false; retaining path /catalog does not remove the changed component.

    URL pair
    https://app.example.com:8443/catalog
    Boundary calculation
    Origin: https://app.example.com:8443
    Result ledger
    Same-origin: false
  3. Site is computed separately

    The selected-domain fixture uses scheme and registrable domain, excluding port.

    URL pair
    https://app.example.com:8443/catalog
    Boundary calculation
    Site: https://example.com
    Result ledger
    Same-site: true
  4. Both results are retained

    Classification is not access permission or network success.

    URL pair
    https://app.example.com:8443/catalog
    Boundary calculation
    Local calculation complete
    Result ledger
    Same-origin: false; same-site: true

HTTP scheme

  1. Pair selected

    The base https://app.example.com/catalog will be compared with http://app.example.com/catalog. The URL pair is ready; origin and site results are not yet computed.

    URL pair
    http://app.example.com/catalog
    Boundary calculation
    Origins: pending
    Result ledger
    Result: pending
  2. Origin tuples are separated

    The changed tuple component is scheme https → http. This HTTP(S) origin comparison gives same-origin=false; retaining path /catalog does not remove the changed component.

    URL pair
    http://app.example.com/catalog
    Boundary calculation
    Origin: http://app.example.com
    Result ledger
    Same-origin: false
  3. Site is computed separately

    The selected-domain fixture uses scheme and registrable domain, excluding port.

    URL pair
    http://app.example.com/catalog
    Boundary calculation
    Site: http://example.com
    Result ledger
    Same-site: false
  4. Both results are retained

    Classification is not access permission or network success.

    URL pair
    http://app.example.com/catalog
    Boundary calculation
    Local calculation complete
    Result ledger
    Same-origin: false; same-site: false

Opaque identities

  1. Two supplied identities

    opaque-A and opaque-B are distinct fixture identities.

    URL pair
    opaque-A / opaque-B
    Boundary calculation
    Comparison: pending
    Result ledger
    Result: pending
  2. Serialization looks equal

    Two distinct opaque identities serialize as the same null text; the text does not establish identity equality.

    URL pair
    Distinct identities
    Boundary calculation
    null / null
    Result ledger
    Identity verdict: pending
  3. Identity rule is applied

    Distinct opaque identities are not same-origin; text equality is insufficient.

    URL pair
    opaque-A ≠ opaque-B
    Boundary calculation
    Identity equality: false
    Result ledger
    Same-origin: false
  4. Model scope is recorded

    This supplied-fixture example created no browser Documents.

    URL pair
    Fixture only
    Boundary calculation
    Internal identities supplied
    Result ledger
    Browser enforcement: not run

ACTORS · STATE · DATA FLOW

Distinguish the hostname from domain boundaries

The hostname of https://app.example.com/catalog is app.example.com. Labels belong to DNS name structure, but the word domain alone does not specify a boundary. Distinguish a full hostname, a public suffix, and a registrable domain when reviewing configuration.

Public suffixes define registration boundaries and can have different lengths, such as com and co.uk. A registrable domain adds the appropriate preceding label. Consequently, taking the final two labels does not work universally. The Public Suffix List supplies boundary data, not proof of domain ownership.

The artifact uses selected ordinary names below example.com and example.org. com/org and the two registrable domains are explicit fixture inputs. It does not reimplement the complete PSL, IDNA, IP handling, or every host form.

Origin identifies a scheme/host/port boundary

For ordinary HTTP(S) URLs, origin comparison uses scheme, host, and normalized port. https://app.example.com/catalog and https://app.example.com/notes?lang=en#new have the same origin: path, query, and fragment do not alter this boundary.

https://api.example.com changes the host; https://app.example.com:8443 changes a non-default port; http://app.example.com changes the scheme. Each differs from the original default-port HTTPS origin, even when one team operates them all.

Normalization matters: https://app.example.com:443 serializes to origin https://app.example.com. URL.origin supplies comparable serializations for these HTTP(S) examples. Origin equality does not require identical raw address strings.

A schemeful site is a broader boundary

For these HTTP(S) domain examples, a schemeful site combines the scheme with the registrable domain. https://app.example.com and https://api.example.com share site https://example.com. Different hosts make them cross-origin while the HTTPS registrable domain makes them same-site.

Ports are excluded from site comparison. https://app.example.com:8443 is cross-origin but same-site relative to the default-port origin. Changing the scheme changes the schemeful site: http://app.example.com is cross-site in this example.

This explanation concerns domain examples. The standard also has host fallback when no registrable domain exists and rules for opaque origins. The selected-domain fixture is not a universal site API for every address type.

Same-site does not grant same-origin authority

Origin is a fundamental browser isolation boundary; site is a different grouping used, for example, in SameSite cookie evaluation. Same-site applications do not thereby receive unrestricted access to each other’s DOM or response bodies. Identify the specific operation and browser policy.

SOP, CORS, and cookie transmission are developed in their own lessons. This table only classifies same-origin and same-site. Cross-origin does not mean all communication is forbidden or that a server certainly never receives a request.

Server authentication and resource authorization remain independent. Before giving Duru an Atlas report, even a same-site API must evaluate principal, tenant, action, and object relationships. A browser boundary does not prove ownership.

Do not reduce an opaque origin to the string null

Origins are not all HTTP(S) tuples. An opaque origin has an internal identity and can serialize as null. Two distinct opaque origins producing the same null string does not establish internal origin equality.

The artifact declares opaque-A and opaque-B as separate identity fixtures: both serialize as null, while identity equality is false. They are explanatory aliases, not actual browser Document origins.

Do not design a policy that treats serialized null as a trusted origin name. The embedding, sandbox, or document context that created the identity matters. This lesson creates no browser sandbox and relaxes no boundary.

2. Red · Trust & Impact

Read every scenario without motion

Site / origin

  1. The trust question selected the right identity

    The base is https://app.example.com/catalog and api.example.com is the subdomain case. Same-site family membership does not produce one origin tuple.

    Identity evidence
    app vs api / shared site
    Boundary comparison
    No boundary comparison
    Access conclusion
    No access claim
  2. Comparison retained information lost in text

    The API host has origin https://api.example.com and site https://example.com. It is not same-origin with the base URL but is same-site. Those results answer different boundary questions.

    Identity evidence
    app vs api / shared site
    Boundary comparison
    Origin false / site true
    Access conclusion
    No access claim
  3. No application-access outcome was added

    Boundary classification is neither an actual browser read-policy nor server-authorization outcome. BrowserEnforcementExecuted=false leaves response readability and user entitlement unknown.

    Identity evidence
    app vs api / shared site
    Boundary comparison
    Origin false / site true
    Access conclusion
    UNKNOWN: actual access
  4. Port and scheme are separate causes

    Port 8443 changes the origin but not the site. HTTP changes both origin and schemeful site; reporting a Boolean pair without its changed component is insufficient.

    Identity evidence
    Host / port / scheme causes separate
    Boundary comparison
    Origin false / site true
    Access conclusion
    UNKNOWN: actual access
  5. The site fixture is not a universal PSL

    fixtureRegistrableDomains defines only app/api.example.com and app.example.org examples. A last-two-label shortcut is not expanded to all suffixes or localhost/IP/opaque contexts.

    Identity evidence
    Host / port / scheme causes separate
    Boundary comparison
    Selected domain map / no universal shortcut
    Access conclusion
    UNKNOWN: actual access
  6. The control preserved the required boundary

    A same-origin requirement retains the complete scheme/host/normalizedPort tuple. Same-site cookie and server-entitlement controls are not substituted for it.

    Identity evidence
    Host / port / scheme causes separate
    Boundary comparison
    Selected domain map / no universal shortcut
    Access conclusion
    Tuple boundary preserved / access unknown

Opaque identity

  1. The trust question selected the right identity

    opaqueComparison provides distinct aliases opaque-A and opaque-B, both serialized as null. Equal text does not mean equal origin identity.

    Identity evidence
    opaque-A ≠ opaque-B / both null
    Boundary comparison
    No boundary comparison
    Access conclusion
    No access claim
  2. Comparison retained information lost in text

    sameOriginIdentity=false is supplied. Serialization comparison loses opaque context type and identity distinction; these aliases do not create actual Document origins.

    Identity evidence
    opaque-A ≠ opaque-B / both null
    Boundary comparison
    Identity false / serialization equality insufficient
    Access conclusion
    No access claim
  3. No application-access outcome was added

    Boundary classification is neither an actual browser read-policy nor server-authorization outcome. BrowserEnforcementExecuted=false leaves response readability and user entitlement unknown.

    Identity evidence
    opaque-A ≠ opaque-B / both null
    Boundary comparison
    Identity false / serialization equality insufficient
    Access conclusion
    UNKNOWN: actual access
  4. Null serialization carries no identity

    opaque-A and opaque-B serialize to the same null text but are distinct identities in the example. Host/port tuple comparison does not apply to these opaque values. Their internal identity distinction cannot be recovered through text equality.

    Identity evidence
    opaque-A ≠ opaque-B; text null / null
    Boundary comparison
    Identity false / serialization equality insufficient
    Access conclusion
    UNKNOWN: actual access
  5. The origin-producing context matters

    In an actual browser review, the Document and embedding/sandbox context establish the origin identity. This alias example creates no Document and treats null text as neither a trusted origin nor an access allowance. Without observing the producing context, that relationship is unknown.

    Identity evidence
    opaque-A ≠ opaque-B; text null / null
    Boundary comparison
    Alias identity supplied; no actual Document
    Access conclusion
    UNKNOWN: actual access
  6. The control preserved the required boundary

    Opaque-identity distinction is retained outside serialization. Actual Document/sandbox context and enforcement require separate evidence; null-text equality grants no allowance.

    Identity evidence
    opaque-A ≠ opaque-B; text null / null
    Boundary comparison
    Alias identity supplied; no actual Document
    Access conclusion
    Opaque identity separate / enforcement unknown

ASSUMPTION · BOUNDARY · CONTROL

Ask which boundary the comparison measures

A shared domain family is insufficient for a technical conclusion. App and API hosts can be same-site but cross-origin; a port change also separates origins. Present the address pair, normalized origins, and site result together.

In the artifact’s API-host branch, parsing produces different origins while the selected PSL fixture produces one site. Substituting the latter for the former misreads the browser trust boundary.

The subdomain and port cases share the false/true pair: cross-origin but same-site. One differs in host, the other in port. Rather than reporting booleans alone, name the changed tuple component so a reviewer can see what the relevant control must preserve.

Separate classification from observed access

Do not infer server responses or user authorization from the origin table. This lesson computes URL tuples without measuring browser read policy, an actual request, or authorization.

The opaque branch demonstrates identities that serialization cannot distinguish. A text-equality audit can be insufficient; preserve the origin type and context as well.

The opaque fixture explicitly supplies distinct identity aliases, but null text carries no such distinction. It cannot tell which identity a browser assigned to a particular iframe. That broader question requires actual Document/sandbox context; the artifact explains a rule without pretending to measure an uncreated browser context.

3. Blue · Secure development & defense

Read every scenario without motion

Domain map

  1. Base origin and site have separate columns

    baseOrigin=https://app.example.com and baseSite=https://example.com. Path/query/fragment changes stay same-origin; site grouping does not authorize a consumer.

    URL matrix evidence
    Base origin / base site separate
    Tuple/domain calculation
    No tuple review
    Change review
    No coverage conclusion
  2. Normalized-port baseline was calculated

    Normalizing explicit port 443 retains origin https://app.example.com. Port 8443 instead gives https://app.example.com:8443 while retaining the site group. Raw URL equality differs from origin-tuple equality.

    URL matrix evidence
    Base origin / base site separate
    Tuple/domain calculation
    443 normalized / 8443 cross-origin
    Change review
    No coverage conclusion
  3. Host-map scope remained explicit

    app and api.example.com map to example.com; app.example.org maps to example.org. This selected map does not compute results for unlisted hosts.

    URL matrix evidence
    com/org fixture map only
    Tuple/domain calculation
    443 normalized / 8443 cross-origin
    Change review
    No coverage conclusion
  4. The scheme negative control was preserved

    HTTP app.example.com has origin=http://app.example.com and site=http://example.com. Its schemeful site differs from HTTPS; this changes a different component from the port rule.

    URL matrix evidence
    com/org fixture map only
    Tuple/domain calculation
    HTTP vs HTTPS / both scopes differ
    Change review
    No coverage conclusion
  5. Observation type remained explicit

    Native URL origin calculation, selected-map site calculation and actual browser enforcement are separate evidence kinds. Without enforcement, no CORS/read-policy or resource allowance is added.

    URL matrix evidence
    com/org fixture map only
    Tuple/domain calculation
    HTTP vs HTTPS / both scopes differ
    Change review
    Parser / fixture / enforcement separate
  6. Change review followed the actual requirement

    Same-host/default-port, subdomain, port, scheme and other-site controls remain together. Not-computed for unknown contexts is more accurate than an unsupported PSL generalization.

    URL matrix evidence
    com/org fixture map only
    Tuple/domain calculation
    HTTP vs HTTPS / both scopes differ
    Change review
    Scoped matrix consistent / unknown retained

Port change

  1. Two ports on the same host were selected

    The base is https://app.example.com/catalog and the comparison is https://app.example.com:8443/catalog. Scheme and hostname match while effective ports differ. No access or network outcome exists yet.

    URL matrix evidence
    app.example.com; HTTPS; 443 / 8443
    Tuple/domain calculation
    Tuple comparison pending
    Change review
    Access unobserved
  2. The port separates origin tuples

    The URL API produces https://app.example.com and https://app.example.com:8443. HTTPS default port 443 normalizes away; non-default 8443 remains. This pair gives sameOrigin=false.

    URL matrix evidence
    Default 443 / explicit 8443
    Tuple/domain calculation
    Same-origin false; different port
    Change review
    Access unobserved
  3. Site calculation excludes the port

    The supplied domain map maps app.example.com to example.com. Both URLs use https, so their site is https://example.com and sameSite remains true. This site equality does not erase the origin difference.

    URL matrix evidence
    https + example.com matches for both URLs
    Tuple/domain calculation
    Same-origin false / same-site true
    Change review
    Access unobserved
  4. A scheme change belongs to another row

    The separate http://app.example.com/catalog row changes both origin and schemeful site. In port-change, the scheme remains HTTPS and same-site stays true. Do not copy the HTTP row’s false site result into this port comparison.

    URL matrix evidence
    Port pair remains HTTPS
    Tuple/domain calculation
    Port pair: false / true; scheme row separate
    Change review
    Access unobserved
  5. A calculation producer is not an enforcement producer

    Origin output comes from the native URL API; site output comes only from the supplied registrable-domain map. Browser response-read policy and server resource policy are separate operations that may consume these values; neither runs here.

    URL matrix evidence
    URL pair and outputs retained together
    Tuple/domain calculation
    Origin API / site fixture / enforcement separate
    Change review
    Coverage limited to calculation; no allowance
  6. The consumer contract must evaluate the new origin

    Moving the API’s own port to 8443 changes the API origin, not automatically the consuming Document’s origin. Review the consumer/API relationship and CORS requirements separately. Remaining same-site does not prove the earlier permission contract still applies.

    URL matrix evidence
    API origin changed; consumer separate
    Tuple/domain calculation
    Same-origin false / same-site true
    Change review
    Classification known; app policy separate

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

Define origin policy with the complete tuple

An ordinary HTTP(S) origin policy evaluates the full scheme, host, and normalized port tuple. Checking only a registrable domain does not satisfy a same-origin requirement; changing a path alone does not change the origin.

When adding a subdomain or port, review cookie, CORS, and server authorization contracts independently. A same-site classification does not automatically validate other controls.

Moving an API from port 443 to 8443 creates a new origin while it can remain same-site. Review permitted browser consumers using origin tuples and user/resource permissions using server policy. A single domain-trusted verdict cannot replace these two decisions; neither supplies the other’s evidence.

Record PSL and exceptional-origin context

For production site calculations, use platform or library behavior with appropriate current PSL data. Do not generalize a final-two-label shortcut from this limited example fixture. IPs, localhost, and opaque contexts need their own rules.

Include pairs for normalized default ports, different ports, subdomains, schemes, and sites in regression observations. Label native parser results, selected-fixture calculations, and actual browser enforcement distinctly.

Keep expectedOrigin and expectedSite as separate columns for the six ordinary URL pairs. The selected domain fixture must not produce a guessed site for an unlisted host. An unknown/not-computed observation for an unsupported context is more accurate evidence than a falsely universal PSL calculation.

NOW APPLY IT TO THE CASE

How are tuples, registrable domains and opaque identities kept separate?

app and api.example.com are same-site but cross-origin. Using port 8443 changes the origin. opaque-A and opaque-B remain distinct supplied identities even though both serialize to null.

Identify the case’s browser and API through URL components. Target, origin and site answer different questions; identify which decision uses each one.

Open the related case file ↗

READ THE EXAMPLE TOGETHER

Origin / schemeful-site comparison matrix

Select a field and examine what it supports and where the evidence ends.

Read the raw artifact and field explanations
{
  "base": "https://app.example.com/catalog",
  "baseOrigin": "https://app.example.com",
  "baseSite": "https://example.com",
  "fixtureRegistrableDomains": {
    "app.example.com": "example.com",
    "api.example.com": "example.com",
    "app.example.org": "example.org"
  },
  "cases": [
    {
      "case": "same-origin",
      "url": "https://app.example.com/notes?lang=en#new",
      "expectedOrigin": "https://app.example.com",
      "expectedSite": "https://example.com",
      "sameOrigin": true,
      "sameSite": true
    },
    {
      "case": "default-port",
      "url": "https://app.example.com:443/catalog",
      "expectedOrigin": "https://app.example.com",
      "expectedSite": "https://example.com",
      "sameOrigin": true,
      "sameSite": true
    },
    {
      "case": "subdomain",
      "url": "https://api.example.com/catalog",
      "expectedOrigin": "https://api.example.com",
      "expectedSite": "https://example.com",
      "sameOrigin": false,
      "sameSite": true
    },
    {
      "case": "port",
      "url": "https://app.example.com:8443/catalog",
      "expectedOrigin": "https://app.example.com:8443",
      "expectedSite": "https://example.com",
      "sameOrigin": false,
      "sameSite": true
    },
    {
      "case": "scheme",
      "url": "http://app.example.com/catalog",
      "expectedOrigin": "http://app.example.com",
      "expectedSite": "http://example.com",
      "sameOrigin": false,
      "sameSite": false
    },
    {
      "case": "other-site",
      "url": "https://app.example.org/catalog",
      "expectedOrigin": "https://app.example.org",
      "expectedSite": "https://example.org",
      "sameOrigin": false,
      "sameSite": false
    }
  ],
  "opaqueComparison": {
    "leftIdentity": "opaque-A",
    "rightIdentity": "opaque-B",
    "leftSerialization": "null",
    "rightSerialization": "null",
    "sameOriginIdentity": false,
    "scope": "Supplied distinct identities, not actual browser Document origin objects"
  },
  "pslScope": "Explicit selected com/org examples only; not a complete PSL implementation",
  "browserEnforcementExecuted": false
}
baseOrigin / baseSite
Two different boundaries for the base address.
cases.sameOrigin
Equality of normalized HTTP(S) tuples.
cases.sameSite
Schemeful-site equality using an explicit registrable-domain fixture.
opaqueComparison
Equal serialization with distinct supplied identities; no browser enforcement.

URL.origin is computed with the native Node API. Site uses the declared fixture domain map; no complete PSL, Document origins, SOP/CORS/cookies, or network executes.

Two reality checks

Same-site applications share same-origin authority.

Subdomains or ports can separate origins. Site classification is not DOM/read permission or object authorization.

Origins serialized as the same null text are equal.

Opaque identities cannot be reconstructed from serialization; distinct identities can share the same text.

YOUR TURN

Work through this story.

Predict the outcome, find the evidence boundary, and explain it in your own words.

Does https://app.example.com:443 share the base origin?

  1. Yes; HTTPS default port 443 is the same effective port.
  2. No; a visible :443 always changes the origin.
Read the explained answer

Yes; HTTPS default port 443 is the same effective port. — Explicit :443 is normalized in the default-port branch; path/query/fragment are not part of the origin tuple.

Two opaque origins serialize as null. Can they be inferred to share an origin?

Selected lesson artifact fields; teaching example

opaqueComparison
{"leftIdentity":"opaque-A","rightIdentity":"opaque-B","leftSerialization":"null","rightSerialization":"null","sameOriginIdentity":false,"scope":"Supplied distinct identities, not actual browser Document origin objects"}
  1. No; supplied opaque-A and opaque-B are distinct identities.
  2. Yes; equal null strings imply equal identities.
Read the explained answer

No; supplied opaque-A and opaque-B are distinct identities. — Serialization is not a unique identity token; sameOriginIdentity=false is supplied explicitly.

api.example.com is same-site but cross-origin. Why does that distinction not grant a sibling app script-read permission?

Read the explained answer

The selected schemeful site matches through the registrable domain; differing hostnames make the origins distinct. Same-site grouping neither removes SOP nor proves a sibling owner trustworthy. This fixture uses only selected com/org PSL examples and executes no browser enforcement.

□ I separated same-site from same-origin.

□ I inferred no read permission from grouping.

Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples

MANUAL LAB

URL Boundary Lab

Predict components, origin/site comparisons, and relative resolution before comparing native API output.

Open the prediction → observation → explanation workbook ↗Source on GitHub ↗

Sources and scope