Phase 14: Security + Storage#
Implement a cookie jar that parses Set-Cookie headers, stores cookies, and attaches them to outgoing requests per RFC 6265bis.
Requirements#
Set-Cookie parsing (RFC 6265bis)#
- Parse Set-Cookie response headers: name=value, Expires, Max-Age, Domain, Path, Secure, HttpOnly, SameSite
- Handle quoted values, whitespace trimming, and case-insensitive attribute names
- Reject cookies with empty names, or names/values containing forbidden characters
Cookie storage#
- Store cookies in a CookieJar struct keyed by (domain, path, name)
- Enforce domain matching: a cookie for .example.com matches sub.example.com
- Enforce path matching: /foo matches /foo/bar but not /foobar
- Expiry: remove expired cookies on access; honor Max-Age over Expires when both present
- Limit total cookies per domain and total jar size (sensible defaults)
Cookie attachment to requests#
- On outgoing requests, select matching cookies by domain, path, and scheme
- Serialize matching cookies into the Cookie header, sorted by path length (longest first)
- Respect Secure flag: only send on HTTPS
- Respect HttpOnly flag: cookies marked HttpOnly are not accessible via document.cookie JS API
- Respect SameSite attribute: Strict (same-site only), Lax (top-level navigations), None (requires Secure)
JS integration#
- Implement document.cookie getter/setter in the JS-DOM bridge
- Getter returns non-HttpOnly cookies for the current document origin
- Setter parses and stores a single cookie (subject to HttpOnly restrictions)
Integration points#
- New module: crates/net/src/cookie.rs (or crates/browser/src/cookie.rs)
- crates/net/src/client.rs: attach cookies to requests, store cookies from responses
- crates/js: implement document.cookie
Acceptance Criteria#
- Set-Cookie headers are correctly parsed (including edge cases: missing value, multiple attributes)
- Domain and path matching follow RFC 6265bis rules
- Expired cookies are not sent and are cleaned up
- Secure cookies are only sent over HTTPS
- HttpOnly cookies are not exposed to document.cookie
- SameSite=Strict cookies are not sent on cross-site requests
- SameSite=Lax cookies are sent on top-level navigations but not subresource requests
- document.cookie getter/setter works correctly
- cargo clippy --workspace -- -D warnings passes
- cargo test --workspace passes