Skip to content

feat(http)!: allowCookies and disallow cookies from caching by default - #58

Merged
pi0 merged 3 commits into
mainfrom
feat/allow-cookies
Jul 8, 2026
Merged

feat(http)!: allowCookies and disallow cookies from caching by default#58
pi0 merged 3 commits into
mainfrom
feat/allow-cookies

Conversation

@pi0x

@pi0x pi0x commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Closes the cookie-related caching gaps from #49 (item 3) and #54 (item 2) with a single, secure-by-default option.

What

Introduces allowCookies?: string[] on defineCachedHandler, and makes cookies non-participating in caching by default.

Default (no allowCookies) — no cookies allowed

Opt-in (allowCookies: ["theme"])

Cookie names are case-sensitive. allowCookies supersedes varies: ["cookie"].

⚠️ Breaking change

Previously the Cookie request header was passed through to the handler and Set-Cookie responses could be stored and replayed. Both now require an explicit allowCookies opt-in. Marked with ! per Conventional Commits.

Implementation notes

  • The Set-Cookie guard inspects res.headers.getSetCookie() in the resolver (lossless) and flags the entry non-enumerably for validate to reject. This avoids Object.fromEntries(headers.entries()) collapsing multiple Set-Cookie values to the last one — which would be a security gap in the allowlist path.
  • No new dependencies; keeps the standalone Request/Response design.

Tests

5 new tests in test/index.test.ts covering: default Cookie stripping + non-varying key, allowlisted key scoping (order-independent), handler-visible Cookie filtering, default Set-Cookie storage refusal (with first-caller passthrough), and the all-cookies-allowlisted requirement for caching Set-Cookie. Full suite: 139 passing; typecheck + lint clean. Docs updated in README.md and AGENTS.md.

🤖 Generated with Claude Code

Introduces `allowCookies?: string[]` on `defineCachedHandler` and makes
cookies non-participating in caching by default (secure default).

BREAKING CHANGE: by default no cookies participate in caching now.
- The `Cookie` request header is stripped before the handler runs and
  never varies the cache key, so a handler can no longer produce
  cookie-dependent output that gets cached and served to other users.
- Any response carrying a `Set-Cookie` header is refused storage — still
  returned to the caller that triggered it, but never cached and replayed
  to other requests (closes the session-leak class from #49).

Set `allowCookies` to opt specific cookie names back in: only those
survive in the handler-visible `Cookie` header and vary the key (sorted,
order-independent, like `allowQuery`), and a `Set-Cookie` response is
cacheable only when every cookie it sets is allowlisted (#54).

The Set-Cookie guard inspects `res.headers.getSetCookie()` (lossless) in
the resolver rather than the serialized headers, which collapse multiple
Set-Cookie values to the last one.

Refs: #49 (3), #54 (2)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@pi0x, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 29 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a95c26f7-3770-4c18-af7b-5719df9f8e43

📥 Commits

Reviewing files that changed from the base of the PR and between 956f513 and d11a945.

📒 Files selected for processing (5)
  • AGENTS.md
  • README.md
  • src/http.ts
  • src/types.ts
  • test/index.test.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/allow-cookies

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Addresses subagent review of #58:

- Fail-safe Set-Cookie guard: on runtimes without `Headers.getSetCookie`,
  fall back to header presence and block conservatively instead of failing
  open (previously `getSetCookie?.() ?? []` silently allowed storing a
  Set-Cookie response where the method was unavailable).
- `allowCookies` now genuinely supersedes `varies: ["cookie"]` by dropping
  `"cookie"` from the varied header names when the allowlist is set, so the
  full raw Cookie header no longer double-varies the key nor strips the
  allowlisted cookie from the handler.
- Normalize `allowCookies` (trim/dedupe names, empty list -> "no cookies").
- Document the custom-`getKey` and request-coalescing caveats.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pi0 pi0 changed the title feat(http)!: allowCookies — disallow cookies from caching by default feat(http)!: allowCookies and disallow cookies from caching by default Jul 8, 2026
Match the plain-expression style of the adjacent allowedQueryNames.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pi0
pi0 merged commit 3f0a45b into main Jul 8, 2026
5 checks passed
pi0x pushed a commit that referenced this pull request Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cache key generation: fix getKey delimiter stripping (#1874) and support cookie-value-based keys (#3061)

2 participants