OCaml HTTP cookie handling library with support for Eio-based storage jars
1# RFC 6265 Compliance TODO 2 3This document tracks deviations from [RFC 6265](https://datatracker.ietf.org/doc/html/rfc6265) (HTTP State Management Mechanism) and missing features in ocaml-cookeio. 4 5## High Priority 6 7### 1. Public Suffix Validation (Section 5.3, Step 5) 8 9**Status:** ✅ IMPLEMENTED 10 11The RFC requires rejecting cookies with domains that are "public suffixes" (e.g., `.com`, `.co.uk`) to prevent domain-wide cookie attacks. 12 13**Implementation:** 14- Uses the `publicsuffix` library which embeds the Mozilla Public Suffix List at build time 15- Validates Domain attribute in `of_set_cookie_header` before creating the cookie 16- Rejects cookies where Domain is a public suffix (e.g., `.com`, `.co.uk`, `.github.io`) 17- Allows cookies where the request host exactly matches the public suffix domain 18- IP addresses bypass PSL validation (per RFC 6265 Section 5.1.3) 19- Cookies without Domain attribute (host-only) are always allowed 20 21**Security impact:** Prevents attackers from setting domain-wide cookies that would affect all sites under a TLD. 22 23--- 24 25## Medium Priority 26 27### 2. IP Address Domain Matching (Section 5.1.3) 28 29**Status:** ✅ IMPLEMENTED 30 31The RFC specifies that domain suffix matching should only apply to host names, not IP addresses. 32 33**Implementation:** 34- Uses the `ipaddr` library to detect IPv4 and IPv6 addresses 35- IP addresses require exact match only (no suffix matching) 36- Hostnames continue to support subdomain matching when `host_only = false` 37 38--- 39 40### 3. Expires Header Date Format (Section 4.1.1) 41 42**Status:** Wrong format 43 44**Current behavior:** Outputs RFC3339 format (`2021-06-09T10:18:14+00:00`) 45 46**RFC requirement:** Use `rfc1123-date` format (`Wed, 09 Jun 2021 10:18:14 GMT`) 47 48**Location:** `cookeio.ml:447-448` 49 50**Fix:** Implement RFC1123 date formatting for Set-Cookie header output. 51 52--- 53 54### 4. Cookie Ordering in Header (Section 5.4, Step 2) 55 56**Status:** ✅ IMPLEMENTED 57 58When generating Cookie headers, cookies are sorted: 591. Cookies with longer paths listed first 602. Among equal-length paths, earlier creation-times listed first 61 62**Implementation:** `get_cookies` function in `cookeio_jar.ml` uses `compare_cookie_order` to sort cookies before returning them. 63 64--- 65 66### 5. Creation Time Preservation (Section 5.3, Step 11.3) 67 68**Status:** ✅ IMPLEMENTED 69 70When replacing an existing cookie (same name/domain/path), the creation-time of the old cookie is preserved. 71 72**Implementation:** `add_cookie` and `add_original` functions in `cookeio_jar.ml` use `preserve_creation_time` to retain the original creation time when updating an existing cookie. 73 74--- 75 76### 6. Default Path Computation (Section 5.1.4) 77 78**Status:** Not implemented (caller responsibility) 79 80The RFC specifies an algorithm for computing default path when Path attribute is absent: 811. If uri-path is empty or doesn't start with `/`, return `/` 822. If uri-path contains only one `/`, return `/` 833. Return characters up to (but not including) the rightmost `/` 84 85**Suggestion:** Add `default_path : string -> string` helper function. 86 87--- 88 89## Low Priority 90 91### 7. Storage Limits (Section 6.1) 92 93**Status:** Not implemented 94 95RFC recommends minimum capabilities: 96- At least 4096 bytes per cookie 97- At least 50 cookies per domain 98- At least 3000 cookies total 99 100**Suggestion:** Add configurable limits with RFC-recommended defaults. 101 102--- 103 104### 8. Excess Cookie Eviction (Section 5.3) 105 106**Status:** Not implemented 107 108When storage limits are exceeded, evict in priority order: 1091. Expired cookies 1102. Cookies sharing domain with many others 1113. All cookies 112 113Tiebreaker: earliest `last-access-time` first (LRU). 114 115--- 116 117### 9. Two-Digit Year Parsing (Section 5.1.1) 118 119**Status:** Minor deviation 120 121**RFC specification:** 122- Years 70-99 → add 1900 123- Years 0-69 → add 2000 124 125**Current code** (`cookeio.ml:128-130`): 126```ocaml 127if year >= 0 && year <= 68 then year + 2000 128else if year >= 69 && year <= 99 then year + 1900 129``` 130 131**Issue:** Year 69 is treated as 1969, but RFC says 70-99 get 1900, implying 69 should get 2000. 132 133--- 134 135## Compliant Features 136 137The following RFC requirements are correctly implemented: 138 139- [x] Case-insensitive attribute name matching (Section 5.2) 140- [x] Leading dot removal from Domain attribute (Section 5.2.3) 141- [x] Max-Age takes precedence over Expires (Section 5.3, Step 3) 142- [x] Secure flag handling (Section 5.2.5) 143- [x] HttpOnly flag handling (Section 5.2.6) 144- [x] Cookie date parsing with multiple format support (Section 5.1.1) 145- [x] Session vs persistent cookie distinction (Section 5.3) 146- [x] Last-access-time updates on retrieval (Section 5.4, Step 3) 147- [x] Host-only flag for domain matching (Section 5.3, Step 6) 148- [x] Path matching algorithm (Section 5.1.4) 149- [x] IP address domain matching - exact match only (Section 5.1.3) 150- [x] Cookie ordering in headers - longer paths first, then by creation time (Section 5.4, Step 2) 151- [x] Creation time preservation when replacing cookies (Section 5.3, Step 11.3) 152- [x] Public suffix validation - rejects cookies for TLDs like .com (Section 5.3, Step 5) 153 154--- 155 156## Extensions Beyond RFC 6265 157 158These features are implemented but not part of RFC 6265: 159 160| Feature | Specification | 161|---------|---------------| 162| SameSite | RFC 6265bis (draft) | 163| Partitioned | CHIPS proposal | 164| Mozilla format | De facto standard | 165 166--- 167 168## References 169 170- [RFC 6265](https://datatracker.ietf.org/doc/html/rfc6265) - HTTP State Management Mechanism 171- [RFC 6265bis](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis) - Updated cookie spec (draft) 172- [Public Suffix List](https://publicsuffix.org/) - Mozilla's public suffix database 173- [CHIPS](https://developer.chrome.com/docs/privacy-sandbox/chips/) - Cookies Having Independent Partitioned State