Description
Cookies set on http://127.0.0.1:8771 are not sent to (nor readable from) http://127.0.0.1:8768 — i.e. the cookie store is scoped per (host, port) even though the cookie has no Domain attribute (host-only cookie), Path=/, and no SameSite restrictions.
Per RFC 6265, host-only cookies are shared across all ports of the same host (cookies are port-agnostic). Chromium behaves this way.
Steps to Reproduce
- Serve two origins on the same host with different ports:
http://127.0.0.1:8771/set (sets Set-Cookie: a=1; Path=/) and http://127.0.0.1:8768/ (a page that reads document.cookie and puts it in document.title).
- In a
moli serve session (CDP), navigate to http://127.0.0.1:8771/set, then navigate to http://127.0.0.1:8768/.
- Observe
document.cookie at the second origin.
Actual Behavior (moli, HEAD @ 3cbc3c2)
127.0.0.1:8771/check after /set: document.cookie === "a=1" ✅
127.0.0.1:8768 same host, different port: document.cookie === "" ❌
- Path scoping works correctly: cookie
b=2; Path=/sub is only sent to /sub/* ✅
HttpOnly cookies are correctly hidden from document.cookie ✅
Expected Behavior
127.0.0.1:8768 should also see document.cookie === "a=1" (port-agnostic host cookie), matching RFC 6265 and Chromium.
Chromium Baseline (131.0.6778.204, headless-shell)
With the same two origins, Chromium does expose a=1 at the other port (CROSS:a=1 observed) — confirming this is a real deviation from Chromium's behavior.
Environment
- moli HEAD @
3cbc3c2 (post-1.0.4), via moli serve --layout
- Verified with CDP
Runtime.evaluate (document.cookie) and the local HTTP server Set-Cookie header
Notes / Possible Location
- The domain matcher in
moli-cookie-store/src/cookie_domain.rs uses url.host_str() (port-stripped) and the connector uses a single shared jar (browser_context.rs storage_partition.cookie_store()), so the port-scoping likely originates at a storage-partition / per-origin jar ownership level rather than the domain matcher.
- Worth a maintainer check: intentional per-origin partitioning (privacy hardening) vs. an accidental port-typed storage key. Real-world impact: local multi-port development flows (e.g.
:3000 frontend sharing a session cookie with :3001 API) and cross-port automation break.
Description
Cookies set on
http://127.0.0.1:8771are not sent to (nor readable from)http://127.0.0.1:8768— i.e. the cookie store is scoped per (host, port) even though the cookie has noDomainattribute (host-only cookie),Path=/, and noSameSiterestrictions.Per RFC 6265, host-only cookies are shared across all ports of the same host (cookies are port-agnostic). Chromium behaves this way.
Steps to Reproduce
http://127.0.0.1:8771/set(setsSet-Cookie: a=1; Path=/) andhttp://127.0.0.1:8768/(a page that readsdocument.cookieand puts it indocument.title).moli servesession (CDP), navigate tohttp://127.0.0.1:8771/set, then navigate tohttp://127.0.0.1:8768/.document.cookieat the second origin.Actual Behavior (moli, HEAD @ 3cbc3c2)
127.0.0.1:8771/checkafter/set:document.cookie === "a=1"✅127.0.0.1:8768same host, different port:document.cookie === ""❌b=2; Path=/subis only sent to/sub/*✅HttpOnlycookies are correctly hidden fromdocument.cookie✅Expected Behavior
127.0.0.1:8768should also seedocument.cookie === "a=1"(port-agnostic host cookie), matching RFC 6265 and Chromium.Chromium Baseline (131.0.6778.204, headless-shell)
With the same two origins, Chromium does expose
a=1at the other port (CROSS:a=1observed) — confirming this is a real deviation from Chromium's behavior.Environment
3cbc3c2(post-1.0.4), viamoli serve --layoutRuntime.evaluate(document.cookie) and the local HTTP serverSet-CookieheaderNotes / Possible Location
moli-cookie-store/src/cookie_domain.rsusesurl.host_str()(port-stripped) and the connector uses a single shared jar (browser_context.rsstorage_partition.cookie_store()), so the port-scoping likely originates at a storage-partition / per-origin jar ownership level rather than the domain matcher.:3000frontend sharing a session cookie with:3001API) and cross-port automation break.