securityaudit.website
Fix guide

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 with Secure. 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.

Want to know if your site has this issue?
Run a free audit →

More guides