Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessSupply crafted URL with CRLF in host
-
DeliveryApplication constructs PSR-7 Uri/Request without sanitization
-
ExploitRequest serialized to raw HTTP/1.x via Message::toString()
-
ExecutionUnvalidated host copied verbatim into Host header
-
PersistInjected CRLF creates attacker-controlled header lines
-
ImpactDownstream proxy or cache processes fabricated headers
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V2 - Validation and Business Logic Input validation, allowlisting
|
| Exploitation Conditions | Exploitation requires all of the following specific conditions to be present simultaneously: (1) the application accepts a user-controlled URL as input (e.g., webhook target, proxy destination, crawl URL, forwarded request); (2) that URL is used to construct a PSR-7 Uri or Request object via guzzlehttp/psr7 version < 2.10.2; (3) the PSR-7 request is serialized into a raw HTTP/1.x byte stream - specifically through GuzzleHttp\Psr7\Message::toString() or a functionally equivalent custom serializer - and no explicit Host header is set before serialization; and (4) the downstream component receiving the serialized request does not independently validate or reject the malformed host. Applications using only Guzzle's standard HTTP client stack (GuzzleHttp\Client::request(), etc.) are explicitly excluded by the vendor as not expected to be vulnerable. The attack is limited to PHP applications with outbound request dispatch flows that manually serialize PSR-7 objects. No special attacker authentication is required; the attacker only needs the ability to supply a URL that the application will use for an outbound request. |
| Impact | The NVD-assigned CVSS 3.1 vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N scores 5.3 (Medium), but this assessment warrants scrutiny on two metrics. First, AC:L overstates ease of exploitation: the vulnerable code path requires manual PSR-7 serialization, a non-default usage pattern explicitly called out in the advisory as distinct from the standard Guzzle client stack. Applications using only Guzzle's standard HTTP client APIs are explicitly not expected to be affected. This substantially narrows the affected population and argues for AC:H in a realistic model. Second, S:U (Unchanged scope) is conservative - the advisory explicitly notes that this malformed request can contribute to request smuggling and cache poisoning in proxy chains, which affects systems beyond the vulnerable application, suggesting a Scope:Changed scenario in those deployments. There is no CISA KEV entry and no confirmed public exploit code, so exploitation probability is currently theoretical. EPSS data was not provided in the input - exploitation likelihood cannot be quantified from available signals. The realistic priority is moderate for applications that manually serialize PSR-7 requests with user-supplied URLs; it is low-to-negligible for the majority of Guzzle users operating through the standard client API. |
| Exploit ScenarioDerived | An attacker submitting a webhook URL or crawl target to a PHP application sends a crafted URL with a host component containing '\r\nX-Forwarded-For: 127.0.0.1\r\nX-Internal-Auth: true'. The application constructs a PSR-7 Request from this URL without sanitizing the host, then serializes it with Message::toString() or a custom transport that writes raw HTTP/1.x to a backend proxy. The proxy interprets the injected CRLF as header boundaries, receiving a request that appears to carry attacker-fabricated headers, enabling cache poisoning of shared responses or bypassing IP-based access controls in multi-tier architectures. No public exploit code has been identified at time of analysis, but the attack primitive is well-understood and reproducible from the advisory description alone. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Jun 11, 2026
CRLF injection in guzzlehttp/psr7 versions prior to 2.10.2 allows remote unauthenticated attackers to inject arbitrary HTTP headers into outbound requests by embedding carriage-return/line-feed sequences in a user-controlled URI host component. When a PSR-7 request is manually serialized into a raw HTTP/1.x message - for example via Message::toString() - the unvalidated host is copied verbatim into the Host header, enabling an attacker-supplied host like '"\r\nX-Injected: yes"' to append controlled headers to the serialized request. In deployments behind proxies, gateways, or load balancers with HTTP/1.1 connection reuse, this header injection can cascade into HTTP request smuggling or cache poisoning. No public exploit code has been identified at time of analysis, and exploitation through the standard Guzzle HTTP client API is explicitly not affected.
RemediationAI
The primary fix is to upgrade guzzlehttp/psr7 to version 2.10.2 or later via Composer: run 'composer require guzzlehttp/psr7:^2.10.2'. The patch is confirmed released and documented in the vendor advisory at https://github.com/guzzle/psr7/security/advisories/GHSA-hq7v-mx3g-29hw. Installations on the 1.x branch will not receive a patch - operators on 1.x must migrate to 2.x or apply compensating controls. If an immediate upgrade is not feasible, the vendor-recommended workaround is to validate and reject all untrusted URI strings before constructing PSR-7 Uri or Request instances, using: preg_match('/[\x00-\x20\x7F]/', $untrustedUrl) and throwing an exception on match. This catches CRLF, tab, space, NUL, and DEL characters. Applications that manually serialize PSR-7 requests or forward raw HTTP messages should additionally ensure the final HTTP client or serializer rejects invalid URI and header data before writing to the network. The input-validation workaround adds a rejection step at the application boundary; its trade-off is that it may refuse some edge-case URLs that are technically valid under RFC 3986 but are unlikely to appear in legitimate production traffic.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in composer, euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
guzzlehttp/psr7 is a PHP implementation of the PSR-7 HTTP message interfaces (RequestInterface, UriInterface, etc.), widely used as a foundational dependency in PHP ecosystems - including as a core component of the Guzzle HTTP client. The CPE cpe:2.3:a:guzzle:psr7:*:*:*:*:*:*:*:* covers all versions prior to the fix. The root cause is CWE-20 (Improper Input Validation): the library failed to reject ASCII control characters (0x00-0x1F), whitespace, DEL (0x7F), and specifically CRLF (0x0D 0x0A) within the host component of a constructed Uri or Request object. HTTP/1.x header framing uses CRLF as the line delimiter, so an injected CRLF in the Host field causes parsers to treat the trailing attacker-supplied bytes as a new, distinct header line. This is a classic HTTP response/request splitting primitive (sometimes tagged 'Code Injection' in this advisory's tags). The vulnerability manifests only during raw HTTP/1.x message serialization - the standard GuzzleHttp\Psr7\Message::toString() path - not during in-memory object manipulation or when using Guzzle's standard transport stack, which performs its own header validation.
Know when Psr7 gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
AC:H reflects the non-default manual-serialization prerequisite; S:C reflects downstream proxy/cache poisoning impact on adjacent systems.
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
1DescriptionCVE.org
guzzlehttp/psr7 is a PSR-7 HTTP message library implementation in PHP. Versions prior to 2.10.2 did not reject ASCII control characters, whitespace, or DEL in first-party URI host components. A vulnerable flow is: First, an application accepts a user-controlled URL. Second, the URL is used to construct a PSR-7 Uri or Request. Third, the host component contains CRLF or another header-unsafe character. Fourth, the host is copied into the PSR-7 Host header when no explicit Host header is provided. Finally, the request is serialized or sent by an HTTP client that does not independently reject the malformed host. In that flow, an attacker can cause the serialized request to contain additional attacker-controlled header lines. For example, a host containing "\r\nX-Injected: yes" can cause the generated Host header to span multiple HTTP header lines. Applications are affected when they use user-controlled URLs for outbound HTTP requests, URL forwarding, proxying, crawling, webhook delivery, or similar request-dispatch flows. In deployments involving HTTP/1.1 connection reuse, proxies, gateways, or load balancers, this malformed request may also contribute to request smuggling or cache poisoning, depending on how downstream components parse the request. The issue is patched in 2.10.2 and later. 1.x is end-of-life and will not receive a patch. As a workaround, validate and reject all untrusted URI strings before constructing PSR-7 Uri or Request instances. Reject input containing ASCII control characters, whitespace, or DEL, including CRLF, tab, space, NUL, or DEL characters. Applications that forward requests should also ensure the final HTTP client or serializer rejects invalid URI and header data before writing requests to the network.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Code injection occurs when an application accepts user input and passes it directly into a language interpreter or evaluator without proper sanitization.
Host validation bypass in guzzlehttp/psr7 before 2.12.3 enables URI authority confusion attacks against PHP applications
Host confusion in guzzlehttp/psr7 (all versions prior to 2.10.2) allows unauthenticated network attackers to supply a ma
EUVD-2026-36240
GHSA-hq7v-mx3g-29hw
NVD
CVE.org
EPSS
Vulnrichment
VulDB
Exploit-DB