Securing Cookies — HttpOnly, Secure, and SameSite Explained
Session cookies are the keys to your users' accounts, yet they're often shipped without the three flags that protect them. If your audit flagged a cookie missing Secure, HttpOnly or SameSite, here's what each one does and how to fix it.
Secure
The Secure flag tells the browser to send the cookie only over HTTPS. Without it, a cookie can be transmitted over plain HTTP — for example on an accidental HTTP link — where anyone on the network can read it. For any cookie that matters, this is non-negotiable.
HttpOnly
HttpOnly makes a cookie invisible to JavaScript: document.cookie simply won't see it. This is your last line of defence against cross-site scripting. Even if an attacker injects a script, they can't read an HttpOnly session cookie and exfiltrate it. Set it on every cookie that doesn't need to be read by your front-end code.
SameSite
SameSite controls whether a cookie is sent on cross-site requests, which is the mechanism behind cross-site request forgery (CSRF). It has three values:
Strict— the cookie is never sent on cross-site requests. Most secure, but it means a user following a link from another site arrives logged out.Lax— sent on top-level navigations (clicking a link) but not on background cross-site requests. A good default for session cookies.None— sent on all cross-site requests, and must be paired withSecure. Only use this for cookies that genuinely need cross-site context.
Putting it together
A hardened session cookie looks like this:
Set-Cookie: session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax
In application code:
// PHP
setcookie('session', $value, [
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
'path' => '/',
]);
// Express
res.cookie('session', value, {
secure: true, httpOnly: true, sameSite: 'lax', path: '/'
});
A note on framework defaults
Many frameworks set sensible defaults now, but not always. Check your session configuration explicitly rather than assuming — the audit checks the cookies your server actually sends, not the ones your config claims to send.
Verify
Re-run the audit. Each cookie should report as hardened, carrying all three flags appropriate to its purpose.
More guides
How to Fix a Missing Content-Security-Policy Header
A missing CSP is the most common high-impact gap we find. Here's how to add one safely without breaking your site.
HSTS Explained — Stop SSL Stripping with Strict-Transport-Security
HTTPS alone doesn't stop downgrade attacks. HSTS does. Here's what the header means and how to deploy it safely.