dotvitals

Loading the list of pages…

↑↓ to moveEnter to openEsc to close

Cookie is shared with every subdomain

Updated

MediumConfirmedweb.cookies.overly-broad-domain

80% of the 397 domains we could check get a warning for this. Sample: the first 1,000 domains by rank in the Majestic Million, checked on 2026-10-12. How we measured

What this check looks for

The cookie carries a Domain attribute, so it is not scoped to this host alone: every subdomain of that domain receives it on every request — including ones you may not control. For a cookie that signs someone in, that hands the login to every subdomain; for a consent flag or an analytics id it costs nothing.

Why it matters

A subdomain is a place the cookie can be taken from: one taken over through a dangling DNS record pointing at a deleted cloud resource, one a third party runs — a help desk, a status page — or a scripting bug on any of them. HttpOnly stops a script reading the cookie but not a hostile subdomain's server, because the browser sends the cookie in the request.

When the check passes, your report says: “The cookie is scoped to this host, not to every subdomain”.

What it costs your score

When this check fails it removes 8 points from your Web security score, before the status, confidence and repeat multipliers are applied. Web security carries a weight of 8 in the overall score.

It shares the web-security.cookies family ceiling of 30 points: however many findings that family produces, together they cannot remove more than that from Web security. One underlying problem showing up in several places is still one problem.

Severity
medium
Default confidence
confirmed
Status when triggered
warn
Deduction
8 points
Family cap
web-security.cookies · 30
Category
Web security
Module
Web cookies
Fix owned by
user
In the ruleset since
2026.09

How the whole score is calculated

How to fix it

Drop the Domain attribute, and give a session cookie the __Host- prefix.

Every subdomain receiving the cookie is another place it can be taken from, and HttpOnly does not stop a hostile subdomain's server from receiving it.

  1. Remove Domain to make the cookie host-only.

  2. For a cookie that signs someone in or carries a token, rename it with the __Host- prefix: the browser then refuses it unless it is host-only, Secure and Path=/, and a subdomain cannot overwrite it.

  3. If you do not know whether a cookie grants access, treat it as though it does until you have checked what reads it.

  4. If a subdomain genuinely needs a cookie, scope it to that subdomain rather than to the whole domain.

How to confirm it worked

  • curl -sSI https://‹host›/ | grep -i '^set-cookie:'

The configuration to publish
Set-Cookie: __Host-{{cookie}}=...; Secure; HttpOnly; SameSite=Lax; Path=/

A named slot like ‹domain› — and the braces left in the configuration below — is filled in with your own values when this rule appears on a report.

Remediation by platform

nginx
# Only for a cookie from an upstream you cannot change. Fix it in the application first.
proxy_cookie_flags ~ secure httponly samesite=lax;
Apache
<IfModule mod_headers.c>
	# Workaround for a cookie from an upstream you cannot change.
	Header always edit Set-Cookie ^((?!.*;\s*Secure).*)$ "$1; Secure; HttpOnly; SameSite=Lax"
</IfModule>
Caddy
header {
	+Set-Cookie "{http.response.header.Set-Cookie}; Secure; HttpOnly"
}
Express
res.cookie('session', value, {
  secure: true,
  httpOnly: true,
  sameSite: 'lax',
  path: '/',
});
  • Requires nginx 1.19.3 or later. This rewrites cookies passing through the proxy; it cannot help for a cookie the browser receives some other way.

  • Shown because the response identified Apache. It is a last resort: set the attributes where the cookie is created. Put it in the virtual host — .htaccess runs too late to edit a header the proxy module has already emitted.

  • Also a workaround; prefer setting the attributes in the application.

Technical detail

‹cookie› sets Domain=‹value›. ‹detail›

RFC 6265bis §5.7 sets the host-only flag *only* when there is no Domain attribute at all. Any value clears it — including one written out as the host itself — and §5.8.3 then sends the cookie to every host that domain-matches it. So Domain= equal to the host is not the same as omitting it: it is the difference between one host and that host plus everything under it.

What the widening costs depends on the cookie, and it is graded that way. A cookie whose name suggests a session or token, or that the server marked HttpOnly, is a warning at medium severity. A cookie whose vendor documents it as carrying no access — an analytics or advertising-measurement id, a consent record, a language preference, a load balancer's affinity — is reported for information and deducts nothing; the list of those names, each with the vendor page it rests on, is in our source. Any other cookie is a low warning at medium confidence: from outside we cannot tell whether it grants access, and treating an unknown cookie as harmless would be a pass nobody checked. A Domain equal to the host is graded low, because the reach is smaller. A cookie the browser discards — a __Host- cookie carrying Domain is one — is reported by the prefix rule instead.

The fix is to drop Domain. Better still is the __Host- prefix: the browser then refuses the cookie unless it is host-only, Secure and Path=/, and a subdomain can no longer set a cookie of that name over it.

Standards and references

Test this on your domain

Run the check that produces this finding, on its own, against any domain.

Open the web cookies checkerBuild the fix