Page MenuHomePhabricator

WebRequest::getCookie may return an array value, causing errors
Closed, ResolvedPublicBUG REPORT

Description

Steps to replicate the issue (include links if applicable):

  • Make a request containing a Cookie header containing cookies used by MediaWiki with values in the form of foo[]=bar;foo[]=bar2, e.g. Cookie: cpPosIndex[]=test;cpPosIndex[]=test2

What happens?:
Various errors occur depending on what cookie(s) you passed. For instance, cpPosIndex causes an HTTP 500:

Uncaught TypeError: Argument 1 passed to Wikimedia\Rdbms\ChronologyProtector::getCPInfoFromCookieValue() must be of the type string or null, array given, called in /srv/mediawiki/php-1.43.0-wmf.2/includes/ServiceWiring.php on line 520 and defined in /srv/mediawiki/php-1.43.0-wmf.2/includes/libs/rdbms/ChronologyProtector.php:645

What should have happened instead?:
No error should have occurred.

Event Timeline

This is apparently a poorly documented quirk of PHP's $_COOKIE handling. WebRequest::getCookie is a thin wrapper around this superglobal. At a quick glance, there is plenty of code that accesses values through this helper and assumes that the return value is either a string or falsy. I think we could either:

  1. Fix all occurrences to check for and handle array values, or
  2. Handle array values in getCookie() and concatenate or otherwise normalize them.

Personally I think option 2 is preferable here, as such array values are hardly expected in normal usage and so it does not seem worth it to pepper the code with array checks everywhere cookies are accessed.

TK-999 triaged this task as Low priority.May 2 2024, 9:29 AM
TK-999 updated the task description. (Show Details)

I'd just return false in that case. This is just PHP being stupid, a cookie called foo[] is not in fact the same as a cookie called foo.

Neither RFC 2109 nor RFC 2965 nor RFC 6265 appear to have an opinion on how to deal with duplicate cookies in an incoming Cookie header.

For "regular" duplicate cookies, e.g. Cookie: foo=bar;foo=baz, PHP will put the value found next to the cookie's first occurrence into $_COOKIES, i.e. bar in this case. Other server software has its own logic, e.g. Eclipse Jersey prefers to use the longest value. In our case, it seems the most straightforward to make the handling of "array-formatted" cookies consistent with regular ones by just taking the first value.

Sorry, just got to the airport and so I hadn't seen your comment @Tgr before posting further. That probably makes more sense than what I was proposing :)

Change #1026503 had a related patch set uploaded (by TK-999; author: TK-999):

[mediawiki/core@master] WebRequest: Gracefully handle array values in getCookie()

https://gerrit.wikimedia.org/r/1026503

Change #1026503 merged by jenkins-bot:

[mediawiki/core@master] WebRequest: Gracefully handle array values in getCookie()

https://gerrit.wikimedia.org/r/1026503

TK-999 claimed this task.