# Cookies have appropriate SameSite attribute

- **Pattern:** `ab-000004` (`security-headers.transport.same-site-cookies`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-17
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000004
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000004)

## Why it matters

Without `SameSite`, browsers send cookies with every cross-origin request — including requests triggered by a third-party page that loads your API. This is the attack surface that CSRF exploits: an attacker's page silently fires a state-changing request (password change, fund transfer, account deletion) and the browser helpfully attaches the user's session cookie. `SameSite=Lax` blocks cookies on cross-origin subrequests while preserving top-level navigations; `Strict` blocks all cross-site cookie sending. OWASP A01 (Broken Access Control) and CWE-352 both identify missing SameSite as a direct enabler of CSRF attacks.

## Severity rationale

Medium because SameSite is a defense-in-depth CSRF control — missing it exposes state-changing endpoints to cross-site request forgery on browsers without default Lax behavior.

## Remediation

Set `SameSite` explicitly on every cookie your application writes. Relying on the browser's implicit default (`Lax` in modern browsers) is fragile — older browsers default to `None`, and future browser policy changes can silently alter behavior.

```ts
// Any cookie-setting location
{ sameSite: 'lax', secure: true, httpOnly: true }
```

Use `Strict` for session tokens on apps with no legitimate cross-site navigation need. Use `None` only when your auth flow requires it (e.g., third-party iframe embeds), and always pair with `Secure` — `SameSite=None` without `Secure` is rejected by modern browsers.

## Detection

- **ID:** `same-site-cookies`
- **Severity:** `medium`
- **What to look for:** Count all cookie-setting locations in the codebase. For each, check the `SameSite` attribute. `SameSite=Lax` or `SameSite=Strict` are acceptable. `SameSite=None` requires `Secure` flag.
- **Pass criteria:** 100% of cookies set by the application have `SameSite` set to `Lax` or `Strict`. If `SameSite=None` is used, the `Secure` flag must also be present. No more than 0 cookies should lack an explicit `SameSite` attribute. Report: "X of Y cookie-setting locations have explicit SameSite attribute."
- **Fail criteria:** No `SameSite` attribute on cookies, or `SameSite=None` without `Secure`.
- **Skip (N/A) when:** No cookies of any kind are set by the application — no Set-Cookie headers, no document.cookie assignments, no cookie library usage.
- **Detail on fail:** `"Session cookie has no SameSite attribute — browsers default to Lax, but explicit is better"` or `"Cookie uses SameSite=None without Secure flag"`
- **Remediation:** The `SameSite` attribute controls when cookies are sent with cross-site requests, helping prevent CSRF attacks. Set it explicitly:

  ```ts
  { sameSite: 'lax', secure: true, httpOnly: true }
  ```

  Use `Lax` for most cases (allows top-level navigations). Use `Strict` for sensitive cookies (blocks all cross-site sending). Only use `None` if your auth flow requires cross-site cookies (e.g., iframe embeds).

---

## External references

- cwe CWE-1275
- cwe CWE-352
- owasp A01

Taxons: access-control, injection-and-input-trust

HTML version: https://auditbuffet.com/patterns/ab-000004
