-
-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add tests for multiple cookies. #19
base: main
Are you sure you want to change the base?
Conversation
According to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie:
IIRC, HTTP/1 user agents are supposed to combine all cookies in a single header, however HTTP/2, for the sake of HPACK, recommends separate cookie headers for each cookie: https://datatracker.ietf.org/doc/html/rfc9113#name-compressing-the-cookie-head |
@jeremyevans do we have any specific guidance in Rack on how to combine The only guidance I can see is:
from https://datatracker.ietf.org/doc/html/rfc3875#section-4.1.18 |
RFC 6265 Section 5.4 states that browsers should not submit more than one |
RFC 6265 Section 5.4 states "When the user agent generates an HTTP request, the user agent MUST NOT attach more than one Cookie header field." RFC9113 doesn't change this semantic but does allow multiple
Therefore, HTTP/2 user agents may emit multiple |
Sort of. Both specs imply that an HTTP/1.1 (non-HTTP/2 context) servers should only accept a 'single octet string'. So, what should non-HTTP/2 servers do? Fail the connection, ignore all cookies lines but the first, or combine them as an HTTP/2 server should? |
According to the CGI specification:
In other words, it's definitely wrong for the server to combine them using a comma, and that could change the semantics of the field, which is in violation of the CGI RFC.
It seems reasonable to me that servers should be robust enough to handle non-compliant requests. In practice, servers should combine multiple cookie headers into a single header value, separated by semi-colons, rather than rejecting the request outright. Maybe we can survey other web servers to see what they do? |
There is a good discussion here from Apache: https://bz.apache.org/bugzilla/show_bug.cgi?id=63434 |
It looks like comma-separated
Therefore, neither cookie-name nor cookie-value can contain commas. Therefore, it might be safe to split on commas. |
In summary, unless you use Falcon, a user agent that submits a request to any other server tested here, with multiple I see three options:
|
Instead of |
I don't think it should be sensitive to whitespace, but at least it is one option to consider some kind of "what works in practice", i.e. |
Not sure what are considered allowable characters in either a cookie key or value (as in I haven't checked unicorn, but I don't recall many (if any) Puma issues related to cookies.
The expectation that servers will properly handle malicious or malformed requests, and also handle any failure in upstream code is certainly my idea of fun... |
This test suite includes test for unicorn and you can see it's failing.
|
Evidence here suggests most servers are just combining it together with What will happen, is that those cookies will get parsed incorrectly. The request may fail, but only if the cookies are critical (e.g. session cookie will be foobar). |
Okay, I have one more data point - Node.js appears to do the correct thing - it concatenates e.g.
Client:
It's not unreasonable to imagine that this scenario would become more common given HTTP/2, and I could imagine load balancers just appending cookie: ... headers to a request to insert extra state tracking. |
Ok, I think Puma should change its behavior... |
If you agree, I'll also try to fix |
Hmm, it also looks like passenger is doing the correct thing - joining using |
Okay, WEBrick is fixed but unreleased. |
c931171
to
248a2d2
Compare
Types of Changes
Contribution