Skip to content

Survey of what most common web apps servers do when receiving invalid cookies in the "Cookie" header

Notifications You must be signed in to change notification settings

dorfsmay/Invalid_cookies_in_Cookie_header

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Invalid cookies in Cookie header

Behaviour not specified for Invalid cookies in the Cookie header

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.

Examples

All RFC compliant cookies

Cookie: SID=31d4d96e407aad42; lang=en-US

Invalid cookie in the header

Cookie: SID=31d4d96e407aad42; muffin ; lang=en-US

History

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 Balancers 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.

Goal

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 valid and invalid coookies.

Contributors

Thanks to all the contributors, regardless of how small the contribution, this effort requires skills in different programing languages and with different libraries, which can only be achieved with a large number of contributors.

How to contribute

Provide a minimalist example of code, as small as possible, using your favourite library which:

  • Listens on port 8080
  • Returns http 200
  • Prints its interpretation of the cookies from the "Cookie" header, be it on stdout, stderr, in the logs or in the http response.
  • Add required extra files or instructions to make it easy to test

Testing

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 cookie: curl -b 'SID=31d4d96e407aad42; muffin ; lang=en-US;' localhost:8080
  • invalid cookies with spaces: curl -b 'SID=31d4d96e407aad42; muffin crumpet cupcake ; lang=en-US;' localhost:8080

List of servers, libraries and results

Use a checkmark ✓/✗ if ending a cookie with a semi-colon is accepted.

Use "discarded", "set as name" or "set as value" to report what is done with invalid cookies.

Please make sure you "ORDER BY language, library;" when adding rows to this table.

server/library version language ending w/ ; valid cookies invalid cookie comments
ring clojure kept discarded Discards invalid values {SID {:value 31d4d96e407aad42}, lang {:value en-US}}
pure go golang kept set as name 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]
gorilla go golang kept set as name same as pure_go
express javascript kept discarded Systematically drops invalid cookies
hapi javascript reject reject Very strict interpretation of the RFC. Reject requests with malformed cookie {"statusCode":400,"error":"Bad Request","message":"Invalid cookie value"}, even for a space between the value and the semi-colon.
django 2.0.4 python kept set as value
bottlepy 0.12.13 python discarded discarded Discards the entire header
Flask 0.12.2 python kept set as name Set invalid cookie as key with empty value
werkzeug 0.14.1 python kept set as name Set invalid cookie as key with empty value
example for copy/paste ✓✗

Value only cookie

It seems that in the early days of the web it was acceptable to use a single cookie without a name. I found one article and a few references in online forums to this behaviour:

Interestingly enough recent versions of both Chromium and Firefox supports this behaviour:

  1. browse to https://api.zioup.com/nonamecookie (This sends a response with header "SetCookie: Look_ma_no_name")
  2. browse to https://api.zioup.com/headers

Observe that the Cookie header is now "Cookie: Look_ma_no_name; BeenThere=1". This probably explains Django's behaviour in setting strings with no equal sign as value. This is interesting from a historical persepective, but given all the security issues due to cookies, it is probably better to simply discard cookies with no equal sign, and probably why the major frameworks are doing so (express, ring).

About

Survey of what most common web apps servers do when receiving invalid cookies in the "Cookie" header

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published