A cookie is a small key/value piece of data the server tells the browser to store via the `Set-Cookie` header, which is then automatically attached to every subsequent request to the same site in the `Cookie` header.
It's the classic way to implement 'state' — login sessions, user identification, preferences — on top of stateless HTTP.
A cookie's attributes drive its security. `HttpOnly` blocks JavaScript's `document.cookie` access, preventing XSS from stealing the cookie (session token); `Secure` sends it only over HTTPS. `SameSite` controls whether the cookie rides cross-site requests (Strict/Lax/None), with Lax/Strict greatly mitigating CSRF (`SameSite=None` requires `Secure`). `Domain`/`Path` set the sending scope, and `Max-Age`/`Expires` set the lifetime.
The 'automatic sending' nature is a double-edged sword: convenient, but even when a user is on a malicious site, the browser auto-attaches the target site's cookie, which is the root cause of CSRF (defended by SameSite and CSRF tokens). A cookie's scoping rules also differ from origin — it can span subdomains and ignores ports. A session cookie usually holds an opaque ID pointing to server-side session state, whereas a JWT keeps state on the client and may also be stored in a cookie. Due to the size limit (~4KB) and the per-request overhead, large data is not put in cookies.