Agent Wranglers

APS-17Required

Set cookies safely or not at all

Set every cookie with Secure and an explicit SameSite. Add HttpOnly to every cookie that no script reads. Use SameSite=None only for a cookie that must work inside another site.

How to do it

Set no cookie you don't need. Otherwise use Secure; HttpOnly; SameSite=Lax (or Strict) and the shortest Max-Age that works. Name it with the __Host- prefix, which needs Path=/, Secure and no Domain, so a subdomain cannot overwrite it. Leave out Domain in general, so the cookie stays on one host. A cookie with SameSite=None also needs Partitioned, unless it must be shared across top-level sites. Sessions have their own rule in lock down session cookies.

Examples

HTTP example

Set-Cookie: __Host-session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=3600

JavaScript example

// Express
res.cookie('__Host-session', sessionId, { path: '/', secure: true, httpOnly: true, sameSite: 'lax', maxAge: 3600_000 });

Python example

# Flask
response.set_cookie("__Host-session", session_id, path="/", secure=True, httponly=True, samesite="Lax", max_age=3600)

How to check

A test reads every Set-Cookie header the site sends. Each has Secure and SameSite, and each one scripts don't read has HttpOnly.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/application-security/authentication-and-sessions/cookie-attributes">Agent Wranglers application security playbook</a>. In code you write, add a comment next to it with the same link.