Skip to content

🐛 bug: enforce CookieJar domain acceptance and host-only cookie matching#4282

Draft
gaby wants to merge 10 commits into
mainfrom
propose-fix-for-cookiejar-vulnerability
Draft

🐛 bug: enforce CookieJar domain acceptance and host-only cookie matching#4282
gaby wants to merge 10 commits into
mainfrom
propose-fix-for-cookiejar-vulnerability

Conversation

@gaby
Copy link
Copy Markdown
Member

@gaby gaby commented May 14, 2026

Motivation

  • A recent change allowed storing cookies under arbitrary Domain attributes and later matching them by suffix, enabling cross-domain cookie injection and host-only leakage when a single CookieJar is reused across untrusted hosts.
  • The fix must enforce the RFC 6265 acceptance rules so origins cannot set cookies for unrelated domains and host-only cookies preserve exact-host semantics.
  • Changes must be minimal and preserve existing domain-cookie behavior for valid parent/suffix matching while preventing the security regressions.

Description

  • Replace the internal hostCookies map[string][]*fasthttp.Cookie with hostCookies map[string][]storedCookie and add a storedCookie{cookie *fasthttp.Cookie, hostOnly bool} to retain host-only semantics.
  • When selecting cookies for a request, skip host-only entries unless the request host exactly equals the stored host and continue to apply suffix matching for domain cookies.
  • When parsing Set-Cookie from a response, reject cookies that carry a Domain attribute unless the response host domain-matches that Domain, and mark cookies without a Domain as hostOnly.
  • Add regression tests Test_CookieJar_HostOnlyCookieNotSentToSubdomain and Test_CookieJar_RejectUnrelatedResponseDomain, and update TestClientResetClearsState to use the new internal storage type.

Copilot AI review requested due to automatic review settings May 14, 2026 11:48
@gaby gaby requested a review from a team as a code owner May 14, 2026 11:48
@gaby gaby requested review from ReneWerner87, efectn and sixcolors May 14, 2026 11:48
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

CookieJar now wraps stored cookies with a hostOnly flag and uses map[string][]storedCookie. Request matching rejects host-only cookies for non-matching hosts. SetByHost/parseCookiesFromResp compute/update hostOnly, adjust domain bytes for host-only cookies, and prune expired entries. New tests cover host-only, domain, and case-matching behaviors.

Changes

Host-only Cookie Security

Layer / File(s) Summary
storedCookie type and retrieval helpers
client/cookiejar.go
storedCookie wrapper introduced; CookieJar.hostCookies changed to map[string][]storedCookie; getCookiesByHost and searchCookieByKeyAndPath refactored to operate on stored entries and release expired cookies.
Host-only filtering in request matching
client/cookiejar.go
cookiesForRequest lowercases host input, prunes expired storedCookie entries while iterating, applies domain match then excludes host-only cookies for non-matching hosts, then applies path and Secure checks and returns copies.
Cookie insertion and response parsing
client/cookiejar.go
SetByHost and parseCookiesFromResp compute hostOnly from presence/absence of explicit Domain, set cookie.Domain bytes for host-only cookies, store/replace entries as storedCookie, update existing entries' hostOnly, and prune/release expired entries by underlying cookie identity.
Tests and client reset update
client/client_test.go, client/cookiejar_test.go
Added cookieKeys test helper; added tests: Test_CookieJar_HostOnlyCookieNotSentToSubdomain, Test_CookieJar_HostOnlyCookieMatchesMixedCaseHost, Test_CookieJar_RejectUnrelatedResponseDomain, Test_CookieJar_MixedHostOnlyAndDomainCookies; updated TestClientResetClearsState to initialize jar.hostCookies as map[string][]storedCookie.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant CookieJar
  participant hostCookiesStorage
  participant NetworkResp
  Client->>CookieJar: cookiesForRequest(host, url)
  CookieJar->>hostCookiesStorage: iterate storedCookie entries
  hostCookiesStorage-->>CookieJar: return underlying *fasthttp.Cookie (skip/release expired)
  CookieJar->>CookieJar: filter by domain, hostOnly, path, Secure
  CookieJar-->>Client: matching cookies

  NetworkResp->>CookieJar: parseCookiesFromResp(resp, host)
  CookieJar->>CookieJar: compute hostOnly, set cookie.Domain bytes for host-only
  CookieJar->>hostCookiesStorage: store/replace storedCookie entries (update hostOnly)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • gofiber/fiber#3564: Both PRs modify client/cookiejar.go's cookie matching/storage logic around domain/host behavior and adjust/add cookie jar tests.

Suggested labels

📜 RFC Compliance

Suggested reviewers

  • sixcolors
  • efectn
  • ReneWerner87

Poem

🐰 I hopped through code to guard each bite,
Cookies wear flags to show what's right.
Host-only fences stop subdomain play,
I nibble bugs and bound away! 🍪✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description provides clear motivation, implementation details, and test coverage plans, but does not follow the repository's required template structure with checkboxes and sections. Restructure the description to match the repository template, including explicit checkboxes for Benchmarks, Documentation, Changelog, Migration Guide, and Type of change sections.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies a bug fix focused on CookieJar domain acceptance and host-only cookie matching, which directly aligns with the main security improvements in the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch propose-fix-for-cookiejar-vulnerability

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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 and usage tips.

@ReneWerner87 ReneWerner87 added this to v3 May 14, 2026
@ReneWerner87 ReneWerner87 added this to the v3 milestone May 14, 2026
@gaby gaby removed the aardvark label May 14, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

Codecov Report

❌ Patch coverage is 77.02703% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.14%. Comparing base (33b7fd4) to head (174a5c2).

Files with missing lines Patch % Lines
client/cookiejar.go 77.02% 12 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4282      +/-   ##
==========================================
- Coverage   91.21%   91.14%   -0.08%     
==========================================
  Files         130      130              
  Lines       12763    12817      +54     
==========================================
+ Hits        11642    11682      +40     
- Misses        709      719      +10     
- Partials      412      416       +4     
Flag Coverage Δ
unittests 91.14% <77.02%> (-0.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@client/cookiejar.go`:
- Around line 121-126: The host-only filter is applied once per bucket which
allows mixed host-only/domain cookies to either be skipped incorrectly or leak;
inside the code that iterates a bucket (the cookies slice returned by
SetByHost/parseCookiesFromResp) move the host-only check into the inner
per-cookie loop (after the expiry prune that updates kept) so each cookie is
individually skipped when cookie.hostOnly && host != domain; update the logic
that appends to the output to only append cookies that pass this per-cookie
host-only test, and add a regression test (e.g., extend
Test_CookieJar_HostOnlyCookieNotSentToSubdomain) that stores both a host-only
and a domain cookie in the same bucket and asserts only the domain cookie is
sent to a subdomain.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c10d7ed5-7f6f-48ce-97f7-b45be3374772

📥 Commits

Reviewing files that changed from the base of the PR and between 33b7fd4 and 4f6e6e6.

📒 Files selected for processing (3)
  • client/client_test.go
  • client/cookiejar.go
  • client/cookiejar_test.go

Comment thread client/cookiejar.go Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the client CookieJar by tracking host-only cookies separately from domain cookies and rejecting response cookies with unrelated Domain attributes.

Changes:

  • Adds storedCookie metadata to preserve host-only cookie semantics.
  • Rejects response cookies whose Domain does not domain-match the response host.
  • Adds regression tests for host-only subdomain leakage and unrelated response domains.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
client/cookiejar.go Updates cookie storage and matching logic to track host-only cookies and validate response domains.
client/cookiejar_test.go Adds regression coverage for host-only and unrelated-domain cookie behavior.
client/client_test.go Updates tests for the new internal storage type and applies formatting changes.

Comment thread client/cookiejar.go Outdated
Comment thread client/cookiejar_test.go
@gaby
Copy link
Copy Markdown
Member Author

gaby commented May 14, 2026

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances the CookieJar implementation by introducing a storedCookie struct to track the hostOnly attribute, ensuring more accurate cookie scoping. It also adds a security check to reject cookies from unrelated domains and includes new test cases for these scenarios. The review feedback correctly identifies a high-severity logic error where the hostOnly check was being applied to an entire bucket based on the first cookie's state rather than per-cookie, which could lead to incorrect cookie transmission to subdomains. Additionally, the reviewer suggested minor performance optimizations to break loops early once a matching cookie is found during updates.

Comment thread client/cookiejar.go Outdated
Comment thread client/cookiejar.go
Comment on lines +205 to +209
for i := range hostCookies {
if hostCookies[i].cookie == existing {
hostCookies[i].hostOnly = hostOnly
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since each cookie (identified by key and path) is unique within the host's cookie slice, you should break the loop once the matching cookie is found and updated for better efficiency.

			for i := range hostCookies {
				if hostCookies[i].cookie == existing {
					hostCookies[i].hostOnly = hostOnly
					break
				}
			}

Comment thread client/cookiejar.go
Copilot AI and others added 2 commits May 14, 2026 12:00
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@client/cookiejar.go`:
- Around line 137-139: cookiesForRequest is doing a case-sensitive host
comparison because the incoming request host (variable host in getByHostAndPath
/ cookiesForRequest) is not normalized to lowercase while stored domain keys
(set via SetByHost and parseCookiesFromResp) are lowercased; fix by lowercasing
the request host once on entry (e.g., at the start of cookiesForRequest or
getByHostAndPath) so subsequent checks like "if sc.hostOnly && host != domain"
and any domainMatch usage compare lowercased values consistently; add/adjust
tests to assert that a host-only cookie set for "example.com" is returned for a
request to "Example.com".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 31f06cdd-147a-483d-8099-606306065e75

📥 Commits

Reviewing files that changed from the base of the PR and between 5685ecb and e2b4d55.

📒 Files selected for processing (2)
  • client/cookiejar.go
  • client/cookiejar_test.go

Comment thread client/cookiejar.go
Copy link
Copy Markdown
Contributor

Copilot AI commented May 14, 2026

@copilot apply changes based on the comments in this thread

Applied the review-thread fixes in ea731bd: host-only filtering now happens per stored cookie, and the regression coverage now exercises mixed host-only/domain cookies in both insertion orders.

Copilot finished work on behalf of gaby May 14, 2026 12:06
@gaby
Copy link
Copy Markdown
Member Author

gaby commented May 14, 2026

@copilot Address all the pull request review comments.

Copy link
Copy Markdown
Contributor

Copilot AI commented May 14, 2026

@copilot Address all the pull request review comments.

Addressed the remaining review comments in a685372: request hosts are normalized before host-only matching, the stored-cookie update loops now break after the match, and there is regression coverage for mixed-case host-only lookups.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread client/cookiejar.go Outdated
Comment thread client/cookiejar.go Outdated
@gaby
Copy link
Copy Markdown
Member Author

gaby commented May 14, 2026

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI commented May 14, 2026

@copilot apply changes based on the comments in this thread

Applied the review-thread fixes in 63e25ac, with a follow-up clarification in b652e78: response cookies now reject public-suffix and IP-literal suffix Domain values, exact-match public-suffix/IP Domain attributes are downgraded to host-only, and regressions cover both cases.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

client/cookiejar.go:288

  • The new response-domain acceptance path only has rejection coverage; there is no parseCookiesFromResp regression test showing that a valid parent Domain (for example, sub.example.com setting Domain=example.com) is still accepted and sent to sibling subdomains. Adding that positive case would guard the stated requirement to preserve valid domain-cookie behavior.
			acceptance := acceptCookieDomain(hostStr, domain)
			if !acceptance.ok {

Comment thread client/cookiejar.go Outdated
Comment thread client/cookiejar.go
@gaby
Copy link
Copy Markdown
Member Author

gaby commented May 14, 2026

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI commented May 14, 2026

@copilot apply changes based on the comments in this thread

Applied the review-thread fixes in 174a5c2: Set/SetByHost now use the same domain-acceptance rules as response parsing, and there is regression coverage for host-only cookies created through response parsing.

Copilot finished work on behalf of gaby May 14, 2026 13:35
@gaby gaby marked this pull request as draft May 14, 2026 13:40
@gaby gaby requested a review from Copilot May 15, 2026 02:27
@gaby gaby moved this to In Progress in v3 May 15, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread client/cookiejar.go
@@ -38,10 +39,21 @@ func ReleaseCookieJar(c *CookieJar) {

// CookieJar manages cookie storage for the client. It stores cookies keyed by host.
type CookieJar struct {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

4 participants