The Cookie header format is specified in RFC 6265, section 4.2.1:
cookie-header = "Cookie:" OWS cookie-string OWS
cookie-string = cookie-pair *( ";" SP cookie-pair )
The individual cookies are clearly delimited by semi-colons, but it is not specified what servers should do when receiving invalid strings between semi-colons.
Cookie: SID=31d4d96e407aad42; lang=en-US
Cookie: SID=31d4d96e407aad42; muffin ; lang=en-US
This repo started as part of a discussion for a Pull Request to the Rust http library, Rust. Pull Request #1159 was created in order to change its behaviour from:
- discarding the entire "Cookie header"
- ignore the last cookie in the header if terminated by a semi-colon
to:
- accept all valid individual cookies within the header, discarding any invalid string between any set of two semi-colon
- accept the last cookie in the header, regardless of being terminated by a semi-colon or not
The latter follows Postel's law, the Robustness principle": "Be conservative in what you send, be liberal in what you accept". Cookies are often injected, therefore added to an existing header in most cases, by intermediary apps servers, security appliances, network devices, proxies, Load Balnacers etc... between the User-Agent and the server. Bugs in any one of these intermediates could inject an invalid cookie. The former behaviour leads to the entire Cookie header to be discarded.
The goal of this survey is to list the behaviours of how well-known Web Application Servers and libraries when receiving a Cookie header containing a mixture of valie and invalid coookies.
Provide a minimalist example of code using your favourite library which demonstrates its behaviour Be conservative in what you send, be liberal in what you accept, and add the result to this file.
Send a request with an invalid cookie between two valid cookies, and one request with only valid cookies but terminated with a semi-colon:
- ending with a semi-column:
curl -b 'SID=31d4d96e407aad42; lang=en-US;' localhost:8080
- invalid cookies:
curl -b 'SID=31d4d96e407aad42; muffin ; lang=en-US;' localhost:8080
Use a checkmark ✓ if the issues are just ignored and the valid cookies are made available, and a crossmark ✗ is the entire header is discarded (no cookie available).
server/library | language | ending w/ ; | invalid cookie | comments |
---|---|---|---|---|
express | javascrit | ✓ | ✓ | |
bottlepy | python | ✓ | ✗ | |
Flask | python | ✓ | ✗ | Does not discard, but the bad and good cookie together: {'SID': '31d4d96e407aad42', 'muffin ; lang': 'en-US'} |
pure go | golang | ✓ | ✓ | Does not discard, assumes K/V pairs and adds an empty value to the invalid cookie value: [SID=31d4d96e407aad42 lang=en-US][SID=31d4d96e407aad42 muffin= lang=en-US] |
example for copy/paste | ✓✗ | ✓✗ | ✓✗ |