Scanverra

How to Fix Insecure Cookie Flags (Secure, HttpOnly, SameSite)

Three attributes on a Set-Cookie header, each closing off a completely different attack. Missing any one of them doesn't just weaken a cookie's security - it leaves a specific, well-understood exploit path wide open.

What Each Flag Actually Stops

  • Secure - the browser will never send this cookie over plain HTTP, only HTTPS. Without it, a session cookie can be sniffed by anyone on the same network as an active man-in-the-middle, or leaked the moment a user follows an old http:// link.
  • HttpOnly - JavaScript (document.cookie) can't read this cookie at all. Without it, a single successful XSS injection anywhere on your site can exfiltrate the session cookie directly, turning a script-injection bug into full account takeover.
  • SameSite - controls whether the cookie is sent on cross-site requests. Without it (or set to None without Secure), the cookie rides along on requests initiated from other sites, which is the mechanism CSRF attacks depend on.

How to Fix It

Set all three explicitly on session/auth cookies

A correctly-flagged session cookietypescript
1Set-Cookie: session=abc123; Secure; HttpOnly; SameSite=Lax; Path=/

Node/Express example

express-session (or any cookie library) configurationtypescript
1app.use(session({
2  secret: process.env.SESSION_SECRET,
3  cookie: {
4    secure: true,     // HTTPS only
5    httpOnly: true,    // no JS access
6    sameSite: "lax",   // blocks most cross-site CSRF vectors
7  },
8}));
  • Strict - the tightest option; the cookie is never sent on any cross-site request, including a user clicking a link into your site from elsewhere.
  • Lax - the sane default for most session cookies; blocks cross-site POSTs (the main CSRF vector) while still allowing the cookie on top-level navigation.
  • None - required for cookies that genuinely need to work across sites (an embedded widget, for example) - but None without Secure is rejected by modern browsers outright.

How Scanverra Detects This

Scanverra's security scan inspects every Set-Cookie header your site sends and flags each cookie missing Secure, HttpOnly, or SameSiteindividually, so you get a specific list of which cookies need which flag rather than a single generic warning.

FAQ

Frequently asked questions

Do I need all three flags on every cookie?

Secure and SameSite are good defaults for essentially every cookie. HttpOnly should be on every cookie your client-side JavaScript doesn't genuinely need to read - which, for session/auth cookies, is almost always the case.

Will SameSite break my login flow if it's behind an SSO redirect?

It can, if you set SameSite=Strict on a cookie that needs to survive a cross-site redirect back from an identity provider. SameSite=Lax still allows top-level navigation (a redirect) to carry the cookie, which is why Lax, not Strict, is the sane default for most session cookies.

Can I set HttpOnly on a cookie my frontend JavaScript reads for a CSRF token?

No - that's a real, legitimate exception. A double-submit CSRF token pattern needs client-side JS to read the cookie value and echo it back in a header, so that specific cookie has to skip HttpOnly. Every other cookie on the same site can and should still have it.

Does Secure mean the cookie is encrypted?

No - Secure only means the browser will refuse to send the cookie over a plain HTTP connection. It doesn't encrypt the cookie's contents; that's what HTTPS in general (and not storing sensitive data in cookies directly) is for.

Free - no sign-up required

Check your cookie flags for free

Run a security scan and see every cookie missing Secure, HttpOnly, or SameSite.

Run free audit