Skip to content

fix(cookie): reject Set-Cookie domains that are public suffixes#2091

Merged
karlseguin merged 1 commit into
lightpanda-io:mainfrom
NYCU-Chung:fix/cookie-public-suffix
Apr 7, 2026
Merged

fix(cookie): reject Set-Cookie domains that are public suffixes#2091
karlseguin merged 1 commit into
lightpanda-io:mainfrom
NYCU-Chung:fix/cookie-public-suffix

Conversation

@NYCU-Chung
Copy link
Copy Markdown
Contributor

parseDomain() rejects bare TLDs (e.g. Domain=.io) but accepts multi-level public suffixes like .co.uk, .com.au, .co.jp.

Per RFC 6265bis §5.7.3.10, user agents should reject cookies whose domain attribute is a public suffix. Chrome, Firefox, and Safari all enforce this using the Public Suffix List.

The PSL data is already imported (Cookie.zig:26) and used in findSecondLevelDomain() (line 559), but parseDomain() does not consult it.

What this fixes

When automating .co.uk / .com.au / .co.jp sites via CDP, cookies that Chrome silently drops are accepted by Lightpanda. This causes cookie jar pollution across unrelated sites in the same session, and behavior differences vs Chrome.

For example, if a site sets Set-Cookie: x=1; Domain=.co.uk, Chrome rejects it, but Lightpanda accepts it and sends that cookie to every .co.uk site visited afterward.

Change

Two lines added after the existing TLD check (line 274):

// Can't set a cookie for a public suffix (e.g. co.uk, com.au).
if (public_suffix_list(owned_domain[1..])) {
    return error.InvalidDomain;
}

Tests added

  • Domain=gov.uk / .gov.uk / api.gov.uk → rejected (using test-mode PSL entries)
  • Domain=example.gov.uk from example.gov.uk and sub.example.gov.uk → accepted (legitimate subdomain cookies still work)

Related: #2088 (also improves parseDomain, different issue — empty domain handling)

parseDomain() rejects bare TLDs (e.g. Domain=.io) but accepts
multi-level public suffixes like .co.uk, .com.au, .co.jp.

Per RFC 6265bis §5.7.3.10, user agents should reject cookies whose
domain attribute is a public suffix. Chrome, Firefox, and Safari all
enforce this using the Public Suffix List.

The PSL data is already imported (Cookie.zig:26) and used in
findSecondLevelDomain(), but parseDomain() does not consult it.

This causes behavior differences vs Chrome when automating .co.uk /
.com.au / .co.jp sites via CDP — cookies that Chrome silently drops
are accepted by Lightpanda, polluting the cookie jar across unrelated
sites in the same session.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 6, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@NYCU-Chung
Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

@karlseguin karlseguin merged commit f28a753 into lightpanda-io:main Apr 7, 2026
12 of 13 checks passed
@karlseguin
Copy link
Copy Markdown
Collaborator

Thanks.

@github-actions github-actions Bot locked and limited conversation to collaborators Apr 7, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants