Agent Wranglers

Security Required

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.

Example

Set-Cookie: __Host-session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=3600
// Express
res.cookie('__Host-session', sessionId, { path: '/', secure: true, httpOnly: true, sameSite: 'lax', maxAge: 3600_000 });
# 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.

For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers website playbook: https://agentwranglers.se/playbook/website/security/cookie-attributes.