A web application can protect its session identifier with HTTPS and HttpOnly and still give more hosts influence over that session than intended. The problem is often the cookie’s Domain attribute.
Suppose the authenticated application is app.example.com, while docs.example.com, status.example.com, and temporary preview hosts live under the same parent domain. If the session cookie is deliberately scoped to example.com, it can be sent to subdomains that do not need it. More broadly scoped cookies also make sibling subdomains part of the cookie’s integrity boundary: a sibling that can set cookies for the parent domain may be able to create a cookie with the same name and interfere with how the application interprets session state.
The defensive rule is simple: give a session cookie the narrowest host scope that satisfies the application requirement. For a session used only by one host, that normally means omitting Domain. Where supported, the __Host- cookie-name prefix lets the browser enforce important parts of that design.
This article explains what host scope changes, why it matters, where the __Host- prefix helps, and when sharing a cookie across subdomains is a legitimate trade-off.
Cookie scope is part of the trust boundary
A cookie is not sent only because its name matches. The browser stores scope information with it and decides which requests receive it.
For host scope, the important distinction is between a host-only cookie and a domain cookie.
If app.example.com sends this response:
Set-Cookie: session=opaque-value; Secure; HttpOnly; Path=/there is no Domain attribute. The cookie is host-only, so it is returned only to app.example.com.
Now compare it with:
Set-Cookie: session=opaque-value; Domain=example.com; Secure; HttpOnly; Path=/This cookie is scoped to example.com and its subdomains. A request to app.example.com can receive it, but so can requests to other matching subdomains.
That difference is easy to treat as routing configuration. For a session credential, it is also a security decision. Every host that receives a bearer session credential becomes another place where disclosure may occur, and hosts able to set parent-domain cookies can affect the cookie state seen by sibling applications.
Start with the narrow requirement
Imagine that only app.example.com needs the authenticated session. The documentation site and status site have separate authentication or no authentication at all.
There is no functional reason for the application session to be shared across those hosts. Adding Domain=example.com therefore increases exposure without providing a benefit.
The smaller design is:
Set-Cookie: session=opaque-value; Secure; HttpOnly; Path=/; SameSite=LaxThe exact SameSite policy depends on the application’s navigation and cross-site requirements, but it does not replace host scoping. SameSite governs when cookies are sent in cross-site contexts. Omitting Domain governs which hosts can receive this cookie.
This separation is useful when reviewing cookie configuration: ask a different question for each attribute instead of treating a collection of flags as one generic “secure cookie” setting.
Broad domains increase both disclosure and integrity risk
The first consequence of a broad Domain is straightforward: more hosts receive the credential.
If a session cookie is scoped to example.com, a request to files.example.com may carry that cookie even if the file service never uses application sessions. A vulnerability, logging mistake, reverse-proxy error, or operational compromise on that additional host can therefore expose a credential that would otherwise never reach it.
There is a second, less obvious problem. Cookies with the same name can coexist when their scope differs. A browser can send more than one matching cookie in a request, while the Cookie request header does not include the original Domain and Path attributes. Server frameworks then have to interpret the resulting name-value pairs.
That means a sibling subdomain should not be allowed to influence the name of a high-value session cookie merely because all hosts happen to share a parent domain. The safest outcome is to make that session cookie host-bound by construction.
This does not mean every compromised sibling subdomain automatically becomes an authenticated user. The effect depends on what cookie the sibling can set and how the target application parses and validates session state. The important defensive point is that unnecessary parent-domain scope creates an avoidable trust relationship.
Use the __Host- prefix to make the intent enforceable
Modern browsers recognize cookie-name prefixes that impose attribute requirements. For a cookie whose authority should belong to one host, __Host- is especially useful.
A cookie with a name beginning __Host- must be set from a secure origin with Secure, must use Path=/, and must not include a Domain attribute. A conforming browser rejects a prefixed cookie that violates those requirements.
A session cookie can therefore look like this:
Set-Cookie: __Host-session=opaque-value; Secure; HttpOnly; Path=/; SameSite=LaxThe prefix does two useful things for the design. It makes the host-only requirement visible in the cookie name, and it asks the browser to enforce the attributes that provide that host-wide scope.
HttpOnly is still valuable because it keeps ordinary page scripts from reading the cookie through cookie APIs. It is not a requirement of the __Host- prefix itself. Likewise, SameSite should still be chosen according to the application’s cross-site request model.
The prefix is defense in depth, not a substitute for reviewing the application architecture. Clients that do not implement a prefix cannot provide its enforcement, so the server should still emit the intended attributes correctly.
Do not confuse host boundaries with origin boundaries
Cookie scoping and the web’s origin model are related but not identical.
An origin includes scheme, host, and port. Traditional cookie host matching does not use port as a boundary in the same way. A host-only cookie is therefore much narrower than a parent-domain cookie, but it should not be described as a complete origin-bound credential mechanism.
This matters when the same hostname serves multiple applications on different ports or when an architecture assumes that cookie scope will isolate applications by port. It will not provide that isolation.
Similarly, Path is useful for controlling when a browser sends a cookie, but it should not be treated as a strong security boundary between mutually untrusted applications on the same host. If two applications require meaningful isolation, separate hosts are usually a clearer boundary than clever cookie paths.
Share a session only when the architecture actually requires it
Sometimes several subdomains intentionally participate in one authenticated application. In that case, a parent-domain cookie may be a deliberate design choice rather than a mistake.
For example, app.example.com and reports.example.com might both need the same browser session. If the session is scoped to example.com, the security model should acknowledge the consequence: all matching hosts that receive or can influence that cookie are now part of the session’s trust boundary.
Before choosing that design, ask whether the hosts are operated to the same security standard, whether less-trusted or user-controlled subdomains exist, and whether the applications could exchange a narrowly scoped authorization result instead of sharing the bearer session itself.
The simpler control is a host-only cookie when one host needs the session. Broader sharing is justified only when the functional requirement outweighs the larger trust boundary and the participating hosts are managed accordingly.
Verify the control in the browser, not only in configuration
Cookie behavior is observable. Verification should confirm what the browser actually stores and sends.
For a host-bound session, check that:
- the response does not include a
Domainattribute; - the stored cookie is host-only;
- requests to sibling subdomains do not carry the session cookie;
- a
__Host-cookie includesSecureandPath=/and is set over HTTPS; - the application continues to authenticate correctly after the cookie name changes, if a prefix is introduced;
- logout, rotation, expiration, and revocation still target the correct cookie.
Also test deployment components that can rewrite cookie attributes. Reverse proxies, gateways, and authentication middleware may modify Domain, Path, or cookie names after application code has generated the response. The browser sees the final Set-Cookie header, not the configuration you intended upstream.
Know what host scoping does not solve
A host-only cookie reduces unnecessary exposure to sibling hosts and reduces their ability to interfere through parent-domain cookie scope. It does not make the session safe against every threat.
If app.example.com itself is compromised, host scoping does not protect the session from that host. If the session identifier is predictable, accepted after revocation, or transmitted without appropriate transport protection, narrowing Domain does not repair those failures. Cross-site request forgery also needs its own defenses; host-only scope does not determine whether a browser sends the cookie during a cross-site request to the legitimate host.
Session security therefore still needs unpredictable credentials, HTTPS, appropriate cookie attributes, bounded lifetime, rotation at important authentication transitions, revocation, and authorization checks on every protected operation.
The value of host scoping is more specific: it removes hosts that do not need the session from the credential’s trust boundary.
Keep the authority as narrow as the requirement
Cookie configuration is easiest to reason about when each attribute answers a concrete security question. For Domain, that question is: which hosts genuinely need this credential?
If the answer is one host, omit Domain and use a host-only cookie. For important host-bound cookies, use the __Host- prefix where supported so the browser can enforce the intended Secure, host-only, host-wide shape.
Share a session across subdomains only as an explicit architectural decision. When a bearer credential is available to more hosts, those hosts become part of the security assumptions around that credential. Keeping the scope narrow reduces those assumptions and leaves fewer systems able to expose or influence the session.