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