https://bz.apache.org/bugzilla/show_bug.cgi?id=63434
--- Comment #7 from [email protected] --- I can confirm I've seen this behavior as well. The problem stems from bad clients under HTTP/1.1. HTTP/2 allows for multiple "Cookie" headers, but the problem shows really when a HTTP/1.1 user-agent incorrectly sends multiple Cookie headers. Apache is compressing them with ", " into one header. This leads to an improper single Cookie value that some language like PHP (or others) will then not be able to properly parse (as commas are allowed characters within the value of a cookie), and because cookie parsers in most interpreters are going to "split" the key-value pairs out of the single Cookie: value by looking for a semi-colon to split on, and then creating the key-value pairs from those. So RFC6265 (https://tools.ietf.org/html/rfc6265#page-7) shows how servers can send multiple "Set-Cookie" headers (to support proxies like load balancers, etc injecting their own cookies), but as the OP stated, 5.4 states the user agent MUST NOT attach more than one Cookie header field" (which is correct for HTTP/1.1) The compression routine in apache is technically not at fault (sort of) because it is combining multiple headers as other RFCs allow, but the issue it would be nice if (for the Cookie header) that httpd could play nice with a bad user-agent, and fix the multiple "Cookie" header mistake the UA makes, so that the parser behind httpd can properly see the values. Scenario 1: Similar example to the OP, imagine a bad UA sends back: Cookie: foo1=hello, world Cookie: foo2=How are you, sam? Current httpd would compress this into: Cookie: foo1=hello, world, foo2=How are you, sam? Then some processor looking at the COOKIE value, would only see a single cookie with the key "foo1" and a value of "hello, world, foo2=How are you, sam?" If the processor were to try and split on the ", " that the apr_table_compress() inserted, it would not properly be able to parse the string because the parts would be: foo1=hello world foo2=How are you sam? However, if the "Cookie" header were given special-case treatment (as would be needed under an HTTP/2 transaction anyhow, then the routine would create: Cookie: foo1=hello, world;foo2=How are you, sam? Which, current processors will properly split with semicolon delimiting that they expect in the Cookie value. In the case of PHP, the current problem with the apr_table_compress() in regard to Cookie is that the resulting $_COOKIE array in that language will miss seeing Cookies that should be present, which can lead to broken SESSION's as the session-id used is stored in the Cookie header---like any other language. We've seen this with incompatible UA's communicating with server banks behind load balancers especially. Scenario 2: UA connects to a server through a proxy like a load balancer that adds its own cookie for state tracking, and a server that adds the cookie value "PHPSESSID" for session tracking. When the server initiates the response back to the UA, it will add something like: Set-Cookie: PHPSESSID=XXXXXXXXXXXX; path=/ On the way through the proxy, the proxy (like and F5 load balancer) adds its own cookie: Set-Cookie: BIGipServer~XXXXX~XXXX=XXXXX; expires=Some date; path=/; Httponly Now, the poor broken HTTP/1.1 User-agent (which is supposed to combine those 2 headers into one, but does not), sends back: Cookie: PHPSESSID=XXXXXXXXXXXX Cookie: BIGipServer~XXXXX~XXXX=XXXXX apr_table_compress() now proceeds to combine those into one header before PHP gets it: Cookie: PHPSESSID=XXXXXXXXXXXX, BIGipServer~XXXXX~XXXX=XXXXX When PHP now looks to find it's session data, it can't find it because the value for "PHPSESSID" now appears as "XXXXXXXXXXXX, BIGipServer~XXXXX~XXXX=XXXXX" Worse yet, if the bad user-agent sends the headers in a different order, PHP won't even find a value at all for "PHPSESSID" because there will be no Cookie that starts like that... for example: Cookie: BIGipServer~XXXXX~XXXX=XXXXX Cookie: PHPSESSID=XXXXXXXXXXXX Would become: Cookie: BIGipServer~XXXXX~XXXX=XXXXX, PHPSESSID=XXXXXXXXXXXX And the only thing then present in $_COOKIE would be the key "BIGipServer~XXXXX~XXXX" with the value "XXXXX, PHPSESSID=XXXXXXXXXXXX" -- You are receiving this mail because: You are the assignee for the bug. --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
