Security Guide

MCP server cookie prefixes security — __Host- and __Secure- prefixes, subdomain cookie injection (cookie tossing), and SameSite comparison

Cookie prefixes are a browser-enforced mechanism that prevent a compromised subdomain from planting a forged session cookie on the main origin. Without cookie prefixes, an attacker controlling evil.skillaudit.dev can set Set-Cookie: session=attacker_token; Domain=skillaudit.dev and the victim's browser silently accepts it, replacing the legitimate session token. The __Host- prefix blocks this entirely: the browser rejects any cookie with this prefix that lacks Secure, Path=/, or that includes a Domain attribute. No subdomain can set a compliant __Host- cookie for another origin.

The cookie tossing attack

Domain-scoped cookies are shared across all subdomains. If your MCP server's session cookie is set as Set-Cookie: session=abc123; Domain=skillaudit.dev; Secure; HttpOnly, any subdomain of skillaudit.dev can also set a cookie named session with a different value and the same domain scope. Because the browser sends all matching cookies sorted by path specificity (most specific first) but otherwise in an unspecified order for same-specificity cookies, the attacker's token may appear before or interleaved with the legitimate token in the Cookie: header. The server reads the first matching cookie name and authenticates the attacker's session token.

This attack requires controlling a subdomain — a realistic scenario when MCP servers are hosted on multi-tenant platforms (e.g., customer.saas.dev), or when a subdomain hosts user-generated content, or when the subdomain's CDN origin is shared. The vulnerability requires no XSS and no CSRF — it is a straightforward cookie scope misuse.

__Host- prefix: the strongest defense

A cookie with the __Host- prefix is accepted by the browser only if ALL of the following are true:

Without the Domain attribute, the cookie is bound to the exact host that set it. A cookie set by skillaudit.dev with no Domain attribute is only sent to skillaudit.dev — not to api.skillaudit.dev or any other subdomain. This eliminates subdomain-scoped injection entirely.

# Correct: __Host- session cookie
Set-Cookie: __Host-session=abc123; Secure; HttpOnly; SameSite=Lax; Path=/

# Browser rejects (has Domain attribute — defeats prefix purpose)
Set-Cookie: __Host-session=abc123; Secure; HttpOnly; SameSite=Lax; Path=/; Domain=skillaudit.dev

# Browser rejects (missing Secure flag)
Set-Cookie: __Host-session=abc123; HttpOnly; SameSite=Lax; Path=/

# Browser rejects (Path is not /)
Set-Cookie: __Host-session=abc123; Secure; HttpOnly; SameSite=Lax; Path=/api/

__Secure- prefix: minimum requirement

The __Secure- prefix requires only that the cookie be set over HTTPS with the Secure flag. It does NOT prevent the inclusion of a Domain attribute. This means a __Secure- cookie can still be domain-scoped and is therefore still vulnerable to cookie tossing from subdomains — but only from HTTPS subdomains, which raises the bar slightly. The main use case for __Secure- is when you need the cookie to be shared across subdomains (e.g., api.skillaudit.dev and skillaudit.dev) while still preventing the cookie from being set over HTTP.

# __Secure- prefix: still allows Domain attribute
Set-Cookie: __Secure-session=abc123; Secure; HttpOnly; SameSite=Lax; Path=/; Domain=skillaudit.dev

__Host- vs __Secure- vs unprefixed: comparison

Property No prefix __Secure- __Host-
Requires Secure flagNoYes (enforced)Yes (enforced)
Requires HTTPS requestNoYesYes
Domain attribute allowedYesYesNo (rejected)
Path must be /NoNoYes (enforced)
Subdomain injection possibleYesFrom HTTPS subdomainsNo
Shared across subdomainsYes (if Domain set)Yes (if Domain set)No (always host-only)
Use for session cookiesNeverOnly if cross-subdomain neededYes — recommended

Relationship to SameSite

SameSite controls whether a cookie is sent on cross-site requests (CSRF defense). Cookie prefixes control whether a cookie can be set by a subdomain with a forged domain scope (cookie tossing defense). They protect against different attack vectors and are complementary:

A complete session cookie for an MCP server should combine both: __Host-session=abc123; Secure; HttpOnly; SameSite=Lax; Path=/. This provides CSRF protection via SameSite and subdomain injection protection via the __Host- prefix.

Browser compatibility

Cookie prefixes are supported in all modern browsers: Chrome 49+, Firefox 50+, Safari 12+, Edge 17+. Internet Explorer does not support cookie prefixes. If your MCP client deployment must support IE (uncommon in 2026), prefixes should still be sent — they are silently ignored by IE, providing no protection there, but they still work correctly in all other browsers. The cookie is stored and sent without the prefix validation in IE, so IE users remain vulnerable to cookie tossing. This is an acceptable tradeoff if IE user population is negligible.

Legacy cookie jars — notably some older mobile WebViews and embedded browser contexts — may also ignore cookie prefixes. SkillAudit's audit report flags if the MCP server's client targets platforms with known prefix non-compliance.

SkillAudit findings for cookie prefix hygiene

HIGHSession cookie set without __Host- or __Secure- prefix and with Domain= attribute — vulnerable to subdomain cookie injection (cookie tossing). Attacker controlling a subdomain can plant a forged session cookie. Score −20.
MEDIUMSession cookie uses __Secure- prefix but not __Host-; Domain= attribute present — still vulnerable to tossing from HTTPS subdomains. Upgrade to __Host- prefix if cross-subdomain sharing is not required. Score −12.
MEDIUMCookie uses __Host- prefix in Set-Cookie header but server also sets same-named cookie without prefix as fallback for legacy clients — attacker can set the unprefixed variant and shadow the prefixed session. Score −10.
LOWCSRF token cookie uses no prefix — subdomain can overwrite CSRF token as well as session cookie, defeating double-submit cookie CSRF protection. Score −6.

Run a SkillAudit scan on your MCP server to check cookie prefix usage across all Set-Cookie response headers, including those from authentication middleware that the MCP skill routes through.