Severity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
UI:N reassigned from provided vector - SSRF bypass via crafted URI requires no human interaction, only attacker-controlled input to an API endpoint; AC:H and C:L/I:L retained as appropriate for host-parsing desync with conditional exploitability.
Primary rating from Vendor (GitHub_M).
CVSS VectorNVD
Lifecycle Timeline
3DescriptionNVD
guzzlehttp/psr7 is a PSR-7 HTTP message library implementation in PHP. Prior to 2.12.3, Uri::assertValidHost() does not reject URI host components containing authority delimiters, embedded ports, or malformed IPv6 brackets, allowing Uri::getHost() to disagree with the URI authority used for security or routing decisions. This issue is fixed in version 2.12.3.
AnalysisAI
Host validation bypass in guzzlehttp/psr7 before 2.12.3 enables URI authority confusion attacks against PHP applications that rely on Uri::getHost() for security-critical decisions. The Uri::assertValidHost() method accepts host strings containing authority delimiters, embedded ports, or malformed IPv6 brackets, causing a semantic split where getHost() returns a sanitized value that disagrees with the actual URI authority used for routing - a classic CWE-436 interpretation conflict exploitable for SSRF allowlist bypass or host-based access control evasion. No public exploit has been identified at time of analysis; vendor-released patch version 2.12.3 resolves the issue.
Technical ContextAI
CWE-436 (Interpretation Conflict) describes vulnerabilities arising when two components parse the same input and reach different conclusions, creating a semantic gap. In guzzlehttp/psr7, the PSR-7 HTTP message interface implementation for PHP, the Uri class is responsible for parsing RFC 3986 URI components. The defect is in Uri::assertValidHost(), which acts as a gatekeeper before values are stored and later returned by getHost(). By permitting host strings such as 'trusted.com@attacker.com', 'trusted.com:8080', or '[::1' (malformed IPv6 bracket), the stored 'host' value diverges from what the URI authority actually encodes. Downstream code relying on getHost() for security decisions - SSRF protection, request routing, allowlist enforcement - operates on the sanitized fragment rather than the full authority, bypassing the intended control. The CPE cpe:2.3:a:guzzle:psr7:*:*:*:*:*:*:*:* covers all prior versions. The fix is in commit ddd64f17d4cc1f7e5ffe6fd2c989ec7221712580 (PR #811).
RemediationAI
Upgrade guzzlehttp/psr7 to version 2.12.3 or later using Composer: run 'composer require guzzlehttp/psr7:^2.12.3' and verify the resolved version with 'composer show guzzlehttp/psr7'. The patch is confirmed in release 2.12.3 per the GitHub release tag (https://github.com/guzzle/psr7/releases/tag/2.12.3) and advisory GHSA-c2w2-prh8-qm98. If an immediate upgrade is blocked by dependency constraints, implement an independent host validation layer at the application boundary: after calling getHost(), also extract and parse the raw URI authority string directly and compare both values - reject any URI where they disagree. This workaround adds code complexity and is brittle against future URI edge cases; treat it as a temporary bridge only. Additionally, audit all application code paths that pass user-supplied URLs to guzzlehttp/psr7 Uri objects and enforce allowlists against the raw authority rather than solely against getHost() output until the upgrade is applied.
CRLF injection in guzzlehttp/psr7 versions prior to 2.10.2 allows remote unauthenticated attackers to inject arbitrary H
Host confusion in guzzlehttp/psr7 (all versions prior to 2.10.2) allows unauthenticated network attackers to supply a ma
Same weakness CWE-436 – Interpretation Conflict
View allSame technique Information Disclosure
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-42319
GHSA-c2w2-prh8-qm98