---
title: "Set cookies safely or not at all · Agent Wranglers"
url: https://agentwranglers.se/playbook/application-security/authentication-and-sessions/cookie-attributes
id: APS-17
level: Required
applies: accounts
risk: takeover
updated: 2026-10-27
build: a2a6bdfed830
tokens: 897
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Set cookies safely or not at all

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Authentication and sessions](https://agentwranglers.se/playbook/application-security/authentication-and-sessions.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: APS-17
- Level: Required
- Chapter: [Authentication and sessions](https://agentwranglers.se/playbook/application-security/authentication-and-sessions.md)
- Rule: 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.
- 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`.
- Risk: An account or system taken over
- Applies when: The project has user accounts.
- How: 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](https://agentwranglers.se/playbook/application-security/authentication-and-sessions/session-cookies.md).

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### HTTP example

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

### JavaScript example

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

### Python example

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

## Sources

- [RFC 6265 (HTTP State Management Mechanism)](https://www.rfc-editor.org/rfc/rfc6265)
- [IETF draft RFC 6265bis (Cookies)](https://datatracker.ietf.org/doc/draft-ietf-httpbis-rfc6265bis/)

## Related rules

- APS-16 [Lock down session cookies](https://agentwranglers.se/playbook/application-security/authentication-and-sessions/session-cookies.md) in Application security
- APS-18 [Block cross-site form posts](https://agentwranglers.se/playbook/application-security/authentication-and-sessions/cross-site-requests.md) in Application security

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/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.

- Previous: [Lock down session cookies](https://agentwranglers.se/playbook/application-security/authentication-and-sessions/session-cookies.md)
- Next: [Block cross-site form posts](https://agentwranglers.se/playbook/application-security/authentication-and-sessions/cross-site-requests.md)
- [Authentication and sessions](https://agentwranglers.se/playbook/application-security/authentication-and-sessions.md)
