Back to HTTP Headers

Cookie auth request

Sends stored cookies back to the server — the client's half of the cookie mechanism, paired with Set-Cookie.

What it does

Cookie is the request header that sends stored cookies to the server. Every time a browser makes a request to a domain, it automatically includes all cookies that match the domain, path, and scope of that request. The server uses these cookies to identify sessions, authenticate users, track preferences, or maintain state across what would otherwise be stateless HTTP requests.

The server sets cookies via Set-Cookie in responses; the browser stores them and sends them back via Cookie in requests. That's the entire cookie mechanism.

Syntax

Cookie: <name>=<value>
Cookie: <name>=<value>; <name2>=<value2>

Multiple cookies are separated by ; (semicolon + space). The browser sends all matching cookies in a single header:

Cookie: session_id=abc123; user_pref=dark_mode; csrf_token=xyz789

There are no attributes here (no HttpOnly, SameSite, etc.) — those only appear in Set-Cookie. The Cookie header is purely name=value pairs.

What the browser sends (and what it doesn't)

The browser automatically sends cookies that match all of these conditions:

  • Domain: cookie domain matches the request host (or is a parent domain)
  • Path: cookie path is a prefix of the request path
  • Secure: if the cookie has Secure flag, only sent over HTTPS
  • SameSite: determines cross-site sending behaviour (see below)
  • Expiry: not expired

The browser does not send:

  • Expired cookies
  • Secure cookies over HTTP
  • HttpOnly cookies via JavaScript's document.cookie (they're still sent in requests though)
  • SameSite=Strict cookies on cross-site navigations
  • SameSite=Lax cookies on cross-site requests that aren't top-level navigations

SameSite and CSRF

SameSite is a Set-Cookie attribute that controls when the Cookie header is sent on cross-site requests. Understanding it is essential for CSRF protection:

SameSite value Sent on same-site requests Sent on cross-site top-level nav (link click) Sent on cross-site subrequests (AJAX, images)
Strict Yes No No
Lax (default in modern browsers) Yes Yes No
None (must also set Secure) Yes Yes Yes

SameSite=Lax (the browser default) provides CSRF protection for most cases: your session cookie won't be sent on cross-site AJAX requests, so a malicious site can't trigger authenticated actions using your session. SameSite=Strict is more secure but breaks OAuth flows and direct links.

Cookie size limits

Browsers enforce limits on cookies:

  • Per cookie: typically 4096 bytes (name + value + attributes)
  • Per domain: typically 50 cookies maximum
  • Total across all domains: varies by browser (several MB)

Exceeding these limits causes cookies to be silently dropped. Store minimal data in cookies — use session IDs that reference server-side state rather than storing large payloads client-side.

Reading cookies in JavaScript

// Read all cookies (httpOnly cookies are NOT accessible)
document.cookie; // "session=abc; pref=dark"

// Parse into an object
const cookies = Object.fromEntries(
    document.cookie.split('; ').map(c => c.split('='))
);

HttpOnly cookies are intentionally inaccessible to JavaScript. They exist in the browser, get sent in the Cookie header on every request, but can't be read or modified by JS — protecting them from XSS attacks.

How it interacts with Set-Cookie

Cookie (request) and Set-Cookie (response) are the two sides of the cookie mechanism:

Server → Client: Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax
Client → Server: Cookie: session=abc123

The Cookie header strips all attributes — it only sends name=value. The browser manages all the attribute-based rules (when to send, over what connections, accessible to JS or not) invisibly.

Common mistakes and gotchas

Storing sensitive data in cookies directly. Cookie values are visible to the client (unless encrypted). Store session IDs that reference server-side state, not the actual sensitive data.

Not setting HttpOnly on session cookies. Without HttpOnly, an XSS vulnerability exposes the session cookie to JavaScript. Always set HttpOnly on authentication cookies.

Not setting Secure on production. Cookies without Secure are sent over HTTP too. Session cookies must have Secure in production.

Expecting Cookie to work across subdomains by default. A cookie set for app.example.com isn't sent to api.example.com. Set Domain=.example.com (with the leading dot) to share cookies across subdomains — but be aware this also makes the cookie accessible to all subdomains, including potentially compromised ones.

Real-world examples

Browser sending multiple cookies:

GET /dashboard HTTP/1.1
Host: app.example.com
Cookie: session_id=8f14e45f; csrf_token=9d5e4b1a; theme=dark

API request with auth cookie:

POST /api/logout HTTP/1.1
Host: api.example.com
Cookie: session_id=8f14e45f; csrf_token=9d5e4b1a
X-CSRF-Token: 9d5e4b1a

FAQ

Is the Cookie header sent automatically by browsers?

Yes — the browser handles it entirely. You don't need to manually set the Cookie header in browser-based requests; the browser includes matching cookies automatically. In non-browser HTTP clients (curl, fetch in Node.js, API clients), you must manage cookies manually.

Can JavaScript read all cookies?

No — only cookies without the HttpOnly flag are accessible via document.cookie. HttpOnly cookies are sent in every HTTP request but are invisible to JavaScript, protecting them from XSS.

Why does the Cookie header not include cookie attributes like HttpOnly or Expires?

Attributes in Set-Cookie are instructions to the browser about how to store and manage the cookie. The Cookie header is purely the client sending back data — the browser has already processed the attributes to decide whether to send the cookie at all. The server doesn't need to receive attributes it originally set.

What's the difference between session cookies and persistent cookies?

Session cookies have no Expires or Max-Age attribute — they're deleted when the browser session ends (when the browser closes, roughly). Persistent cookies have an explicit expiry and survive browser restarts. Both are sent identically via the Cookie header while they're valid.

Fun fact

Cookies were invented by Lou Montulli at Netscape in 1994, originally to solve a specific problem: shopping cart state for an online store (MCI). The name "cookie" comes from "magic cookie" — a Unix computing term for a token passed between programs. Montulli's original implementation was in Netscape Navigator 0.9 beta, and within months every major web server was supporting them. The Cookie/Set-Cookie header pair became the de facto standard for stateful web sessions before any formal specification existed — RFC 2109 wasn't published until 1997, three years after cookies were already everywhere.

Related Headers