◇ Web Security

Secure Cookies: HttpOnly, Secure, and SameSite Explained

Cookies carry the session identifiers and tokens that keep users logged in, which makes them a frequent target for attackers. Secure cookies are those configured with the right attributes, principally HttpOnly, Secure, and SameSite, so that stealing or abusing them becomes far harder. Setting these flags correctly is one of the highest-value, lowest-effort improvements you can make to a web application's session security.

How Cookies Are Set

A server sets a cookie with the Set-Cookie response header, and the browser returns it on subsequent requests to the matching site. The attributes appended to that header control when and how the cookie is sent:

Set-Cookie: session=8f2a...; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=3600

Each attribute addresses a specific threat, and using them together provides layered protection for the session identifier.

The HttpOnly Attribute

The HttpOnly attribute prevents client-side scripts from reading the cookie through document.cookie. Its purpose is to limit the damage of cross-site scripting: even if an attacker injects JavaScript, they cannot directly exfiltrate an HttpOnly session cookie.

It is important to understand the boundary of this protection. HttpOnly does not prevent XSS or stop an attacker from making requests as the user through injected script; it only keeps the cookie value out of JavaScript's reach. Apply it to every cookie that the browser does not legitimately need to read.

The Secure Attribute

The Secure attribute tells the browser to send the cookie only over encrypted HTTPS connections. Without it, a cookie can be transmitted over plaintext HTTP, where a network attacker could capture it. Marking session cookies Secure ensures they are never exposed on an unencrypted channel. Combined with serving the whole site over HTTPS and using HSTS, this closes the gap where a session token could leak in transit. Note that Secure governs transmission only; it does not encrypt the cookie's contents, so sensitive values should remain opaque references rather than readable data.

The SameSite Attribute

The SameSite attribute controls whether a cookie is sent on cross-site requests, and it is the primary browser-level defense against cross-site request forgery. It has three values:

  • Strict: the cookie is withheld from all cross-site requests, including top-level navigations from another site. This is the safest option but can log users out when they arrive via external links.
  • Lax: the cookie is sent on top-level navigations using safe methods, such as clicking a link, but not on cross-site subrequests or form posts. This balances usability and protection and is a common default.
  • None: the cookie is sent on all cross-site requests and must be paired with Secure. Use it only when a cookie genuinely needs to work in a third-party context.

Even with SameSite, anti-CSRF tokens remain valuable as defense in depth, since browser behavior and edge cases vary.

Scope Attributes and Prefixes

Domain and Path

The Domain and Path attributes control which requests receive the cookie. Keep scope as narrow as the application allows; a cookie scoped to a broad parent domain is exposed to every subdomain, widening the attack surface. Omitting Domain restricts the cookie to the exact host that set it, which is usually safer.

Lifetime

Max-Age and Expires set how long a cookie persists. Session identifiers should be short-lived and rotated after privilege changes such as login, which limits the window in which a stolen cookie is useful. A cookie with no Max-Age or Expires is a session cookie that the browser discards when it closes, which suits many authentication scenarios; persistent cookies survive restarts and should be reserved for cases where a longer-lived token is genuinely required.

Two special prefixes let a cookie assert its own security requirements, which the browser enforces:

  • **__Secure-** requires the cookie to be set with the Secure attribute over HTTPS.
  • **__Host-** additionally requires no Domain attribute and a Path of /, binding the cookie tightly to the single origin that set it. This helps prevent subdomains from overwriting sensitive cookies.

A Practical Configuration Checklist

  1. Set HttpOnly on every cookie the front-end does not need to read.
  2. Set Secure on all cookies and serve the site exclusively over HTTPS.
  3. Choose SameSite=Lax or Strict for session cookies, reserving None for genuine cross-site needs.
  4. Narrow Domain and Path, and prefer the __Host- prefix for sensitive session cookies.
  5. Keep lifetimes short and rotate identifiers after authentication.
  6. Continue to use anti-CSRF tokens alongside SameSite.

These settings work best as part of a broader defense that includes output encoding, a strong Content Security Policy, and careful session management, as explored across K0G.

Key Takeaways

  • Secure cookies use HttpOnly, Secure, and SameSite to protect session identifiers from theft and misuse.
  • HttpOnly keeps cookies out of JavaScript, limiting the impact of cross-site scripting but not preventing it.
  • Secure ensures cookies travel only over HTTPS, and SameSite is the main browser defense against CSRF.
  • The __Host- and __Secure- prefixes let cookies enforce their own scope and transport requirements.
  • Narrow cookie scope, short lifetimes, and complementary anti-CSRF tokens complete a strong configuration.
cookiesweb-securitysession-securitycsrfbrowser-security

Frequently asked questions

What are secure cookies?

Secure cookies are HTTP cookies configured with protective attributes, chiefly HttpOnly, Secure, and SameSite, that reduce the risk of theft and misuse. These attributes control whether client-side scripts can read a cookie, whether it is sent only over encrypted connections, and whether it accompanies cross-site requests. Applying them correctly is a foundational step in protecting session and authentication cookies.

What does the HttpOnly cookie attribute do?

The HttpOnly attribute tells the browser to hide a cookie from client-side JavaScript, so it cannot be read through the document cookie interface. This limits the damage of a cross-site scripting attack, because injected scripts cannot directly steal an HttpOnly session cookie. It does not prevent XSS itself, but it removes one of the easiest ways for injected code to exfiltrate session tokens.

What does the SameSite cookie attribute do?

The SameSite attribute controls whether a cookie is sent with requests originating from other sites, which is the core defense against cross-site request forgery. Strict withholds the cookie on all cross-site requests, Lax sends it only on top-level navigations using safe methods, and None sends it in all contexts but requires the Secure attribute. Choosing Lax or Strict blocks the typical CSRF scenario where a third-party page triggers an authenticated request.

What is the difference between the Secure and HttpOnly cookie attributes?

The Secure attribute ensures a cookie is only transmitted over encrypted HTTPS connections, protecting it from being intercepted on the network. The HttpOnly attribute hides the cookie from client-side JavaScript to limit theft through cross-site scripting. They defend against different threats, network interception versus script-based exfiltration, so sensitive cookies should typically set both.

How do you secure session cookies?

Secure session cookies by setting HttpOnly to block script access, Secure to require HTTPS, and an appropriate SameSite value such as Lax or Strict to limit cross-site sending. Scope cookies tightly with the Path and Domain attributes, keep session lifetimes short, and consider host-only or prefixed cookies for extra binding. Together these attributes protect against theft, interception, and cross-site request forgery.

Does SameSite fully prevent CSRF?

SameSite significantly reduces cross-site request forgery by keeping cookies off most cross-site requests, but it is best used as one layer rather than the sole defense. Gaps can remain from same-site attacks, certain navigation types under the Lax setting, and inconsistent behavior across older browsers. Combining SameSite cookies with anti-CSRF tokens provides more reliable protection.

Try it hands-on

K0G is an open toolkit of browser-based security utilities — hashing, encoding, JWT, certificates, crypto and more, all running locally in your browser.

Explore the tools →