php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78844 FPM does not support multiple HTTP request headers with the same name
Submitted: 2019-11-20 17:39 UTC Modified: 2023-02-09 16:31 UTC
Votes:5
Avg. Score:3.8 ± 0.7
Reproduced:4 of 4 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (25.0%)
From: mikk150 at gmail dot com Assigned: bukka (profile)
Status: Not a bug Package: FPM related
PHP Version: 7.3.11 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: mikk150 at gmail dot com
New email:
PHP Version: OS:

 

 [2019-11-20 17:39 UTC] mikk150 at gmail dot com
Description:
------------
PHP $_SERVER['HTTP_*'] superglobal and getallheaders() does not actually give all headers.
If you have multiple header lines with same name, each SAPI does totally different thing(and all of them are wrong)

If I make request:
GET / HTTP/1.1
Forwarded: for=10.0.0.1,for=20.30.40.50;host=php.net,host=awesome.proxy.com;proto=https,proto=http
Forwarded: for=10.30.20.10;host=second.awesome.proxy.com;proto=http

I get 3 different responses based on SAPI

FPM only keeps last header
php -s only keeps first header
apache concatenates them with ,

PHP should implement new method to get all headers OR implement some class that has method to get all headers


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-11-20 18:44 UTC] mikk150 at gmail dot com
-Summary: Ability to get all client headers +Summary: Ability to get all client sent HTTP headers
 [2019-11-20 18:44 UTC] mikk150 at gmail dot com
summary more understandable
 [2019-11-20 19:03 UTC] requinix@php.net
-Summary: Ability to get all client sent HTTP headers +Summary: FPM does not support multiple HTTP request headers with the same name -Type: Feature/Change Request +Type: Bug -Package: *Web Server problem +Package: FPM related
 [2019-11-20 19:03 UTC] requinix@php.net
The ability to get headers is highly dependent on the SAPI. Apache's works nicely, but php -s is just a quick development server that is not going to be suitable for all purposes.

So really, the issue here is that php-fpm doesn't properly handle multiple headers. The HTTP spec requires that multiple headers only be allowed when their values can be combined into comma-separated lists, which means $_SERVER and getallheaders() are still sufficient.
 [2019-11-20 20:06 UTC] mikk150 at gmail dot com
Ah, I can see that now, I actually understood https://tools.ietf.org/html/rfc7239#section-4 incorrectly.

I undestood that
GET / HTTP/1.1
Forwarded:for=10.0.0.1;host=php.net;proto=https
Forwarded:for=20.30.40.50;host=awesome.proxy.com;proto=http
Forwarded:for=10.30.20.10;host=second.awesome.proxy.com;proto=http

would become
GET / HTTP/1.1
Forwarded:for=10.0.0.1,for=20.30.40.50,for=10.30.20.10;host=php.net,host=awesome.proxy.com,host=second.awesome.proxy.com;proto=https,proto=http,proto=http


but it actually states that each field-value(seperated by semicolon) MUST NOT occur more than once per field-value

which means Apache is correct
GET / HTTP/1.1
Forwarded:for=10.0.0.1;host=php.net;proto=https,for=20.30.40.50;host=awesome.proxy.com;proto=http,for=10.30.20.10;host=second.awesome.proxy.com;proto=http

As this is actually correct
 [2023-02-09 16:31 UTC] bukka@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: bukka
 [2023-02-09 16:31 UTC] bukka@php.net
This is actually a server issue as it should convert it to the comma separated list as CGI spec does not allow multiple headers with the same name. This is actually what was fixed in nginx relatively recently: https://hg.nginx.org/nginx/rev/f8f6b9fee66a
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 06:01:30 2024 UTC