Cookie Prefixes: Strengthening Session Security
I have spent a disproportionate amount of time looking at session management implementations this year. It is a recurring theme at the moment for me. You would think by now we would have solved basic cookie security, yet here we are. Developers rely heavily on flags like Secure and HttpOnly, but these can be circumvented through clever injection.
Enter cookie prefixes. They are not a silver bullet, but they force the browser to play by your rules.
The Fundamental Flaw
The core issue with standard cookies is that the server cannot guarantee the browser will respect requested security attributes. If an attacker controls a subdomain or a man-in-the-middle position, they can often overwrite your sensitive session cookies with their own malicious versions. The browser just either accepts the update or would have no idea that the upstream had later injected cookies. The server would be equally clueless too — cookies sent by the browser are just name/value pairs, their attributes do not get transmitted anywhere. This leaves your authentication state wide open to compromise.
Cookie prefixes shift the power back to the server by making the name of the cookie dictate its security constraints.
__Secure-
This is the baseline for modern apps. When you prefix a cookie name with __Secure-, the browser refuses to store it unless it is set with the Secure flag and originated from a secure HTTPS connection.
It effectively prevents an insecure, non-HTTPS site from overwriting your secure session cookie. Simple, but effective.
__Host-
If you need higher assurance, use __Host-. This prefix carries the same requirements as __Secure- but adds significantly stricter rules:
- Host-Only: The cookie is locked to the domain that set it. It cannot be shared with subdomains.
- No Domain Attribute: You are explicitly forbidden from setting the
Domainattribute. This stops the common trick of forcing a cookie onto parent domains. - Path Restriction: The cookie must be set with
Path=/.
By using __Host-, you are telling the browser that this cookie belongs exclusively to the current origin. It is the best defence against subdomain takeover attacks where a compromised sub-site tries to hijack the session of the main application.
The Ultimate Fix: __Host-Http-
The strongest option available is __Host-Http-. It combines every restriction of __Host- with one more: the cookie must also carry the HttpOnly flag. This proves the cookie was set via a Set-Cookie header rather than JavaScript, and it prevents any client-side script from reading or modifying it.
The result is a cookie that is bound to a single origin, transmitted only over HTTPS, inaccessible to JavaScript, and guaranteed to have been created by the server. It is the closest browsers currently allow to treating the origin as a true security boundary.
Implementation Reality
Implementation is straightforward. Rename your session cookie from session_id to __Host-Http-session_id. Update your backend to read the new name. Most frameworks handle prefixed cookies without issue. If you are still using legacy session code, this is a good reason to modernise it.
Of course, you have to update your backend code to look for the new name. Most modern frameworks handle this without much fuss. If you are still relying on legacy session management, this is a good excuse to refactor that layer.
Don’t wait for a session hijacking incident to decide your cookies need better protection. It is a low-effort configuration change that removes an entire class of cookie-based injection risks. Do it today.