Comments (9)
So it's a kind of little
BC Break
too :)
Looks like a regular bug/regression to me.
I get wierd URI from
ServerRequestFactory::fromGlobals
with port duplicated likehttps://host:port:port/path
.
@3DFace would you be able to provide a failing test case? See tests introduced in e08e52e for reference.
from laminas-diactoros.
It depends if the upstream webserver is something like nginx
, Caddy
or apache2
: all of those are very popular, and de-facto standards (regardless of what Mozilla says)
from laminas-diactoros.
Hm, I am not 100% sure if the port is expected to be passed via X-Forwarded-Host
.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host
Did we properly support that edge-case before?
from laminas-diactoros.
I just got this exact same problem when using local-ssl-proxy in my dev env (it sends the port as part of XFH header).
This should work as a temporary fix:
if (($uri = $request->getUri()) && ($port = $uri->getPort()) && (str_ends_with($uri->getHost(), ":$port"))) {
$request = $request->withUri($uri->withHost(substr($uri->getHost(), 0, -strlen((string)$port) - 1)));
}
from laminas-diactoros.
The question is, what port has the higher priority?
X-Forwarded-Port
or X-Forwarded-Host
?
Thats why a unit test is needed since I have no clue what the expected behavior is.
I stick with it that at least the non-browser-specific mozilla documentation says that X-Forwarded-Host
does NOT contain a port.
It depends if the upstream webserver is something like
nginx
,Caddy
orapache2
: all of those are very popular, and de-facto standards (regardless of what Mozilla says)
Got that, but what if all behave different? Pretty sure we are not providing per-server features.
FWIW
NGINX does document X-Forwarded-Host
header without port:
https://www.nginx.com/resources/wiki/start/topics/examples/forwarded/
Caddy refers to Mozilla doc when it comes to X-Forwarded-Host
:
https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#defaults
Apache2 states that X-Forwarded-Host
contains the value of the original Host
header (which usually does not include port):
https://httpd.apache.org/docs/2.4/en/mod/mod_proxy.html#x-headers
So apache2 seems to be the one who also adds :port
to X-Forwarded-Host
since Host
header (as per mozilla can contain the port.
The only thing I wonder is: what if these ports do differ. What if the Host
header contains port 80 while the originating request was sent to 443. Thats why I'd say we should probably just ignore that there can be a port within X-Forwarded-Host
and just strip it.
I just got this exact same problem when using local-ssl-proxy in my dev env (it sends the port as part of XFH header).
This should work as a temporary fix:
if (($uri = $request->getUri()) && ($port = $uri->getPort()) && (str_ends_with($uri->getHost(), ":$port"))) { $request = $request->withUri($uri->withHost(substr($uri->getHost(), 0, -strlen((string)$port) - 1))); }
Could you probably provide your stack? I've quickly jumped into the source of local-ssl-proxy
and it uses http-proxy
which only passes X-Forwarded-For
, X-Forwarded-Port
, X-Forwarded-Proto
from incoming requests:
So I can only guess that there has to be another HTTP Server in front of the proxy which already passes invalid X-Forwarded-Host
, maybe even the same webserver as the author of this issue uses.
from laminas-diactoros.
In my case, chrome
-> local-ssl-proxy
-> php built-in server
.
Looking at the code of http-proxy, I guess the problem relates to this line:
https://github.com/http-party/node-http-proxy/blob/9b96cd725127a024dabebec6c7ea8c807272223d/lib/http-proxy/passes/web-incoming.js#L85
Note that in the end it defaults to the host header, which at some point also included the port.
If I remember my original problem, it was about the port being duplicated in the url (causing a broken url).
from laminas-diactoros.
Yah, thanks for feedback @uuf6429! I've discovered the same from the apache documentation. They do pass Host
header as well which (at least due to the Mozilla documentation) can contain a port.
I have no clue why it is allowed to have a port via Host
since the connection can be initiated against port 443 (SSL) while the Host
header can still contain Port 80 🤷🏼♂️
Not 100% sure but I guess that NGINX and Caddy are actually removing any port from Host
as it has nothing to do with what was actually connected to.
i.e.:
$ curl -H "Host: localhost:80" https://localhost:443/
So what should the X-Forwarded-Port
or the port returned from UriInterface#getPort
represent?
from laminas-diactoros.
My thoughts on this are are:
$uri->getHost()
should definitely be fixed - it shouldn't contain a port (the fix itself shouldn't break anything)- the original headers should stay as they were, even if contradictory (
forwarded_host=hosXt:portX, forwarded_port=portY
) - if there is a clear case of portX preferred over portY because "it's always so", maybe consider following that logic..
- ..otherwise, keep the current logic and discard the extra port when it is set twice
- ..and maybe trigger a warning/log message when both are set to different values
- or if we want to be extremely strict about it, reject the request with status 503 or similar.
I have a strong opinion for point 1 & 2. In case of 3 & 4, I think we should strongly consider point 5.
from laminas-diactoros.
Should be fixed as of 2.24.0
from laminas-diactoros.
Related Issues (20)
- [RFC]: Allow better constraint handling for PHP HOT 2
- Could ServerRequestFactory::marshallUriFromSapi() be made public? HOT 4
- Update to PSR-7 1.1/2.0 HOT 2
- Remove image stream compatibility from `Stream`
- CVE-2023-29530: Fix For PHP 7.4 HOT 16
- CLI command to register diactoros as pinned for `php-http/discovery`
- Drop deprecated function marshalUriFromSapi
- PhpInputStream::getContent() inconsistency HOT 9
- RFC: Read php input stream content into php temp stream to allow all stream features in PhpInputStream HOT 1
- Numeric header names handling in PSR-7 message objects
- V3 getBody()->getContents() no longer returns full stream on second call HOT 3
- `composer.json` provides non-existing versions of `psr/http-factory`
- security vonerability HOT 1
- Plus signs in cookie data get converted to space.
- marshal_headers_from_sapi.php line 29 HOT 2
- `Uri::__toString()` can yield malformed URIs HOT 2
- 2.x series does not support PHP 8.3 HOT 20
- [RFC]: Remove `scheme` filtering HOT 3
- Malformed request causes 500 response HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from laminas-diactoros.