OSV 1.4.0 · github-reviewed · 修改于 2026-07-22 02:35
发布时间
2026-07-22 02:35
GitHub 审查时间
2026-07-22 02:35
NVD 发布时间
2026-07-09 01:17
源文件
advisories/github-reviewed/2026/07/GHSA-c2w2-prh8-qm98/GHSA-c2w2-prh8-qm98.json
guzzlehttp/psr7 did not reject URI host components containing authority delimiters (/, ?, #, @, or \), an embedded port such as host:8080, or IPv6 brackets that do not frame the host (such as [::1 or ::1]). Uri::assertValidHost() rejected only control characters, so these malformed hosts were accepted both when parsing a URI string — including through new Uri(), an absolute-form request target passed to Message::parseRequest(), and the synthetic SERVER_NAME or SERVER_ADDR fallback used by ServerRequest::fromGlobals() — and when setting a host with Uri::withHost(). Because the stored host was not validated, Uri::getHost() could return a value that does not agree with the URI's authority or with the host that is actually used on the wire. For example, Uri::withHost('[email protected]') is accepted, and new Uri('http://[gggg::1]/') produces a getHost() of '[gggg:' while getAuthority() returns '[gggg::1'.
You are affected if your application builds a Uri or calls Uri::withHost() with host data that is wholly or partly attacker-controlled and then relies on Uri::getHost() for a security or routing decision, such as host allowlisting or denylisting, an SSRF guard, cookie scoping, or proxy-bypass selection. You are also affected if you parse, forward, proxy, or re-serialize URIs that come from untrusted raw HTTP messages or from synthetic $_SERVER values. Because getHost() can then disagree with the real connection target, the concrete impact depends on how your application and any downstream HTTP/1.x component use the URI, and may include host-based access-control bypass, server-side request forgery, routing to an unintended host, or Host header confusion. You are not affected if every host you place into a Uri is already trusted and well formed.
Applications using are affected in the same way through Guzzle's use of PSR-7. Guzzle derives the request header from the request URI, and its cookie matching and proxy-bypass matching both read . An application that builds a Guzzle request URI from attacker-controlled host input can therefore have its header, cookie scope, or proxy-bypass decision computed against a host that differs from the one Guzzle connects to. This is not the normal request-sending path, and an application that passes only trusted, well-formed URIs to Guzzle and never builds a request URI from attacker-controlled host input is not affected through Guzzle's standard client APIs.
guzzlehttp/guzzleHostno_proxyUri::getHost()HostThe issue is patched in 2.12.3 and later. Starting in that release, guzzlehttp/psr7 rejects URI host components that contain authority delimiters, an embedded port, or IPv6 brackets that do not frame the host, both when parsing a URI and via Uri::withHost(), so Uri::getHost() agrees with the URI authority. A framed bracketed literal whose contents are not a valid IPv6 address is preserved rather than rejected, so getHost() still agrees with the authority.
If you cannot upgrade immediately, validate and normalize host values before you build or modify a Uri from untrusted input, and do not treat Uri::getHost() as a trust boundary for a host you have not independently checked. Before passing a host to Uri, reject any value that contains /, ?, #, @, or \, that contains a colon outside a bracketed IPv6 literal, or that has unbalanced brackets. Applications that parse, forward, replay, or re-serialize raw HTTP messages, or that run with attacker-controlled $_SERVER values, should validate the host before calling Message::parseRequest() or ServerRequest::fromGlobals(), and should avoid reparsing untrusted input.