If your application uses cookies for authentication, you’re already relying on one of the most sensitive pieces of data in your entire tech stack. Session cookies effectively are the user’s identity. If an attacker gets hold of one, they don’t need a password – they can often just reuse the session.

The problem is that browsers won’t warn you when you configure cookies insecurely. The following way of setting a cookie with a session identifier is a perfectly valid HTTP request line:

Set-Cookie: sessionid=abc123

Look familiar? It works, it ships, and it raises no errors. It also leaves your application exposed.

Most cookie security issues come down to missing flags – small configuration details that are easy to skip and hard to notice. The good news is that fixing them is straightforward once you know what to look for.

Why cookie misconfiguration keeps happening

Cookie security isn’t new by any means, but the defaults are still working against you. The HTTP cookie specification pre-dates modern web threats, and browsers prioritize compatibility over security. This has some risky consequences for web application security:

  • Insecure cookies are accepted without warnings
  • Security flags are opt-in, not enforced
  • Misconfigurations don’t break functionality but do increase risk

This permissive default behavior means that, especially under time pressure, it’s all too easy to just ship the simplest thing that works while omitting crucial security settings.

The secure baseline every session cookie should follow

At a minimum, a session cookie should look like this:

Set-Cookie: sessionid=abc123; HttpOnly; Secure; SameSite=Strict

Each cookie attribute here exists to stop a specific class of attack:

  • HttpOnly – prevents JavaScript from reading the cookie (mitigates cookie theft through cross-site scripting)
  • Secure – ensures the cookie is only sent over HTTPS (reduces man-in-the-middle interception risk)
  • SameSite=Strict – blocks the cookie from being sent with cross-site requests (mitigates CSRF attacks)

When it comes to cookie flags, more isn’t always better. In this example, you may notice there’s no Domain, no Expires, and no Max-Age – and that’s because for session cookies, omitting these is often the more secure choice.

How to set cookie security flags in practice

Here are some examples of creating the above cookie with baseline security flags in commonly used frameworks.

Node.js / Express

// Insecure basic cookie creation when you just want it all to work
res.cookie('sessionid', 'abc123');

// Secure
res.cookie('sessionid', 'abc123', {
  httpOnly: true,
  secure: true,
  sameSite: 'strict'
});

Python / Django

# Secure if cookie security settings are also enabled
response.set_cookie(
  'sessionid',
  'abc123',
  httponly=True,
  secure=True,
  samesite='Strict'
)

Note that Django only applies these protections if you enable SESSION_COOKIE_SECURE and SESSION_COOKIE_HTTPONLY in your settings. These are not enabled by default.

PHP (modern syntax)

// Secure — using the options array (PHP 7.3+)
setcookie('sessionid', 'abc123', [
  'httponly' => true,
  'secure'   => true,
  'samesite' => 'Strict'
]);

Understanding cookie security flags

The list below provides an at-a-glance, strictly practical overview of security-related cookie attributes. See the cookie security whitepaper for a detailed discussion and RFC 6265 for the official specification of HTTP Cookie and Set-Cookie header fields.

HttpOnly flag: Protect against client-side cookie access

The HttpOnly flag prevents client-side scripts from accessing cookies via document.cookie. This is critical for reducing the impact of cross-site scripting vulnerabilities.

Without HttpOnly, any XSS issue becomes a session hijacking issue. With it, attackers need a more complex exploit chain to extract session data.

Note that HttpOnly does not protect against cookie overwriting. An attacker who can execute JavaScript in the victim’s browser can flood the domain’s cookie storage, force eviction of the HttpOnly cookie, then recreate it with an attacker-controlled value – a technique known as cookie jar overflow. The risk in this case isn’t theft but session fixation.

Secure flag: Enforce encrypted transport

The Secure flag ensures that cookies are only sent over HTTPS connections. Without it, cookies can be transmitted in clear text if a request falls back to HTTP. This matters even if your site uses HSTS (HTTP Strict Transport Security) to enforce SSL/TLS encryption by default – all it takes is one misconfigured endpoint or redirect for sensitive information to leak.

One nuance that often gets overlooked is that Secure protects confidentiality, not integrity. An attacker can’t intercept and read the cookie over plain HTTP, but they may still be able to manipulate requests in certain scenarios.

SameSite: Controlling cross-site behavior

SameSite is a crucial flag but also one of the most frequently misconfigured. The three possible values are:

  • SameSite=Strict – cookie is never sent with cross-site requests
  • SameSite=Lax – cookie is sent on top-level navigation (the default in Chrome and Edge, but not all browsers)
  • SameSite=None – cookie is sent in all contexts, including third-party requests

Browser behavior for this flag varies – Firefox and Safari apply their own tracking protections instead of relying purely on the SameSite attribute. The safest approach is to always set SameSite explicitly. For most session cookies, Strict is the right choice.

If you genuinely need cross-site behavior – for example, in OAuth flows or embedded applications – you must explicitly set:

Set-Cookie: sessionid=abc123; SameSite=None; Secure

Note that without Secure, modern browsers will reject the cookie entirely.

Expiry attributes: When persistence can be a risk

There are two main types of cookies:

  • Session cookies – deleted when the browser closes
  • Persistent cookies – stored for a defined period using Max-Age or Expires

Note that if you set both Max-Age and Expires, Max-Age takes precedence and the browser ignores Expires. So in the following example, the Expires value will be ignored:

Set-Cookie: sessionid=abc123; Max-Age=3600; Expires=Fri, 01 Jan 2099 00:00:00 GMT

Modern browsers also enforce a hard cap on cookie lifetimes – for example, Chromium-based browsers limit persistence to around 400 days, regardless of longer values set using flags.

For authentication, shorter lifetimes reduce risk. In many cases, using session cookies with no explicit expiry is the safer default.

Domain and Path: Limiting exposure

The Domain and Path attributes control where cookies are sent:

  • Setting a broad Domain value (such as example.com) makes the cookie available to all subdomains
  • Omitting Domain restricts scope to the originating host

The Path attribute works the same way, so a cookie set with Path=/admin is only sent to URLs under that path, not to the rest of the application. As with the Domain attribute, the default (the path the cookie was set from) is usually the right choice.

The narrower the scope, the smaller the attack surface. Unless you have a clear requirement, avoid unnecessarily expanding cookie scope using Domain or Path.

What cookie flags don’t protect you from

Cookie flags reduce risk, but they don’t eliminate it. For example:

  • HttpOnly doesn’t fix XSS – it just limits what attackers can extract.
  • SameSite reduces CSRF risk, but doesn’t replace proper CSRF protection.
  • Secure doesn’t prevent all man-in-the-middle attacks.

These issues rarely exist in isolation. A missing HttpOnly flag might seem minor on its own, but combined with an XSS vulnerability it becomes a direct path to session hijacking. The same applies to weak SameSite settings and CSRF exposure.

Secure baseline cookie flags to adopt

If you’re unsure where to start, here’s a practical baseline:

  • Use HttpOnly for all session cookies.
  • Use Secure everywhere – no exceptions in production.
  • Set SameSite=Strict unless you have a specific reason not to.
  • Avoid setting Domain or Path unless required.
  • Prefer session cookies or short-lived tokens over persistent cookies.

This set won’t solve every problem or work for every situation, but it’s a solid starting point for eliminating the most common and easily exploitable misconfigurations that could expose sensitive data.

Conclusion: Closing the gap between configuration and real risk

Secure cookie flags are a basic application security best practice and provide a good first line of defense, but they are not a guarantee of actual secure cookie behavior in the live app. They also won’t eliminate an underlying XSS vulnerability that makes HttpOnly necessary, or a CSRF exposure that a SameSite flag is trying to limit. Finding and fixing those issues requires testing your application for vulnerabilities, not just setting the right attributes.

Acunetix identifies missing and misconfigured cookie security attributes alongside the underlying vulnerabilities – such as XSS and CSRF – that make cookie flag issues exploitable. Request a demo to see dynamic vulnerability scanning at work.

FAQs about cookie security flags

Cookie security flags are attributes set in the Set-Cookie header that control how cookies behave in the browser. The most important flags are HttpOnly, Secure, and SameSite, which help protect cookies from theft, interception, and misuse in attacks like XSS and CSRF.

The HttpOnly flag prevents client-side scripts from accessing cookies via JavaScript. This reduces the risk of session theft through cross-site scripting (XSS), but it does not prevent attackers from overwriting cookies if they can execute code in the browser.

Use SameSite=Strict for maximum protection when your application does not require cross-site requests. Use SameSite=Lax if you need cookies to be sent during top-level navigation, such as when users follow links to your site. Always set the flag explicitly instead of relying on browser defaults.

The Secure flag ensures cookies are only sent over HTTPS connections. Without it, cookies may be exposed if a request is made over plain HTTP, increasing the risk of interception in man-in-the-middle attacks.

No. Cookie flags reduce risk but do not fix underlying vulnerabilities. For example, HttpOnly does not prevent all XSS, and SameSite does not replace proper CSRF protection. You still need secure coding practices accompanied by application security testing to identify and fix root causes.

SHARE THIS POST
THE AUTHOR
Zbigniew Banach
Zbigniew Banach
Technical Content Lead & Managing Editor
Cybersecurity writer and blog managing editor at Invicti Security. Drawing on years of experience with security, software development, content creation, journalism, and technical translation, he does his best to bring web application security and cybersecurity in general to a wider audience.