Back to Glossary
medium severity · Vulnerability Glossary

Insecure Cookies (Missing Secure & HttpOnly)

Updated August 8, 2026

4 min read

insecure cookies
missing secure flag
missing httponly flag
secure cookie attribute
httponly cookie
cookie security
session cookie theft
set-cookie secure httponly

Insecure cookies are session or authentication cookies sent without the Secure and/or HttpOnly attributes. The check is a one-line look at your Set-Cookie headers; the fix is setting both flags where the cookie is created.

What is an insecure cookie?

A cookie's security depends less on its value than on the attributes attached to it in the Set-Cookie response header. Two of those attributes matter most for session and auth cookies:

  • Secure tells the browser to send the cookie only over HTTPS. Without it, the cookie is also attached to plain-http:// requests to your domain.
  • HttpOnly hides the cookie from client-side JavaScript. Without it, any script running on the page can read the cookie value through document.cookie.

An insecure cookie is one where either flag is missing on a cookie that carries a session or credential. It's a default-configuration problem: many frameworks and older setups issue cookies with neither flag unless you opt in. This maps to OWASP A05: Security Misconfiguration.

A third attribute, SameSite, controls whether a cookie rides cross-site requests and is a separate finding with its own missing SameSite cookie entry — set it too, but the Secure and HttpOnly gaps described here are independent of it.

Why it's a risk / how it's exploited

Each missing flag opens a different door.

Missing Secure — network capture. Even if your login page is HTTPS, a cookie without Secure is attached to any http:// request the browser makes to your domain — a mistyped link, an old bookmark, a hardcoded http:// asset. An attacker sharing the victim's network (public Wi‑Fi, a rogue access point, a compromised upstream proxy) can read that request in the clear and lift the session cookie. From there they replay it and are logged in as the victim, no password required.

Missing HttpOnly — XSS becomes session theft. HttpOnly does not stop cross-site scripting; a script injected through an XSS flaw still runs. What it does is remove the session cookie as the prize: with HttpOnly set, document.cookie can't see it, so the attacker can't simply read and exfiltrate the token. Without it, a single reflected or stored XSS turns into full account takeover in one line of injected JavaScript.

Honestly, both of these need a precondition — a network position, or an existing XSS bug — so on their own they're rated medium, not critical. But they're cheap to fix and they strip the payoff from two of the most common attack paths, which is exactly why scanners and auditors flag them.

How to detect it

Read your Set-Cookie headers and check each cookie for both tokens:

curl -sI https://example.com | grep -i set-cookie

A safe session cookie shows both flags: Set-Cookie: sessionid=...; Path=/; Secure; HttpOnly; SameSite=Lax. A vulnerable one is missing one or both — e.g. Set-Cookie: sessionid=...; Path=/ has neither. You can also open browser DevTools → ApplicationCookies and read the Secure and HttpOnly columns per cookie.

To check this across every page and cookie your app sets — alongside the rest of your response headers — run the security headers checker, or a full website vulnerability scan that flags insecure cookies together with the rest of your OWASP Top 10 exposure.

How to fix it

Set the flags where the cookie is created — at the application/framework level, which is the correct layer because that's the code that knows which cookies are sessions. Most frameworks expose this on the cookie or session config directly:

// Express / typical Node session config
cookie: { secure: true, httpOnly: true, sameSite: 'lax' }

When you can't touch the app, add a proxy-level backstop.

nginx (1.19.3+):

proxy_cookie_flags ~ secure httponly;

Apache (mod_headers) — use edit* so the rewrite applies to every Set-Cookie header, not just the first:

Header edit* Set-Cookie ^(.*)$ "$1; Secure; HttpOnly"

Two caveats. Don't set HttpOnly on a cookie a legitimate front-end script must read (some CSRF-token or feature-flag cookies are read by design) — it will break that code. And require HTTPS site-wide (redirect all HTTP to HTTPS, ideally with HSTS) so that adding Secure never silently drops a cookie a page still needs over http://. After deploying, re-run the curl -sI check and confirm every session cookie shows Secure; HttpOnly.

FAQ

Does HttpOnly stop XSS? No. It doesn't prevent the injected script from running or acting on the page. It only stops that script from reading the cookie through document.cookie, which removes session theft as the easy win — you still need to fix the underlying XSS.

My login page is already HTTPS — do I still need Secure? Yes. Without Secure, the browser will still attach the cookie to any http:// request to your domain, so a single insecure link or asset is enough to leak it on a hostile network. Pair Secure with HttpOnly and a SameSite value for defense in depth.


Not sure which of your cookies ship without Secure or HttpOnly? Run a free website vulnerability scan to check your cookie attributes and the rest of your web attack surface in one pass.