Skip to content

Update dependency guzzlehttp/psr7 to v3 [SECURITY]#13

Open
renovate[bot] wants to merge 1 commit into
masterfrom
renovate/packagist-guzzlehttp-psr7-vulnerability
Open

Update dependency guzzlehttp/psr7 to v3 [SECURITY]#13
renovate[bot] wants to merge 1 commit into
masterfrom
renovate/packagist-guzzlehttp-psr7-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
guzzlehttp/psr7 ^1.8.2^3.0.0 age confidence

guzzlehttp/psr7 has Host Confusion via Authority Reinterpretation

CVE-2026-48998 / GHSA-34xg-wgjx-8xph

More information

Details

Impact

guzzlehttp/psr7 improperly interpreted malformed Host header values when constructing request URIs from inbound request data. This issue concerns inbound request parsing and server request construction. It does not require serializing a PSR-7 request, and it is not part of the normal outbound request-sending path used by guzzlehttp/guzzle.

A vulnerable flow is:

  1. An attacker controls a raw HTTP request or server variable containing a Host value.
  2. The Host value contains URI authority delimiters, such as trusted.example@evil.example.
  3. guzzlehttp/psr7 uses that value to construct a URI.
  4. The URI parser treats the portion before @ as userinfo and the portion after @ as the URI host.
  5. The resulting PSR-7 request URI host differs from the original Host header value.

For example, Host: trusted.example@evil.example can result in a PSR-7 URI whose host is evil.example, while the original Host header value remains trusted.example@evil.example.

Applications are affected if they parse attacker-controlled raw HTTP requests with GuzzleHttp\Psr7\Message::parseRequest() or the legacy 1.x GuzzleHttp\Psr7\parse_request() function, or if they build server requests from attacker-controlled server variables with GuzzleHttp\Psr7\ServerRequest::fromGlobals() or GuzzleHttp\Psr7\ServerRequest::getUriFromGlobals(), and then rely on the resulting URI host for routing, allow-list checks, credential selection, or forwarding decisions. Applications using guzzlehttp/psr7 only through Guzzle's standard HTTP client APIs are not expected to be affected. In affected forwarding or gateway scenarios, this may cause requests or credentials to be sent to an unintended host.

Patches

The issue is patched in 2.10.2 and later. 1.x is end-of-life and will not receive a patch.

Workarounds

If you cannot upgrade immediately, validate Host values before passing untrusted request data to Message::parseRequest(), legacy 1.x parse_request(), ServerRequest::fromGlobals(), or ServerRequest::getUriFromGlobals().

Accept only uri-host [ ":" port ]. Reject values containing whitespace, control characters, userinfo (@), path (/ or \), query (?), fragment (#), malformed IP literals or bracket syntax, or invalid port syntax.

Do not validate Host by prefixing it with http:// and passing it to parse_url(), because that can reinterpret malformed values as URI userinfo and host.

References

Severity

  • CVSS Score: 5.3 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


guzzlehttp/psr7 has CRLF Injection via URI Host Component

CVE-2026-49214 / GHSA-hq7v-mx3g-29hw

More information

Details

Impact

guzzlehttp/psr7 did not reject ASCII control characters, whitespace, or DEL in first-party URI host components. The issue requires a PSR-7 request to be serialized into a raw HTTP/1.x message, for example with GuzzleHttp\Psr7\Message::toString() or an equivalent custom serializer. Creating a Uri, Request, or other PSR-7 object alone is not sufficient. The malformed host must be copied into the serialized Host header without further validation.

A vulnerable flow is:

  1. An application accepts a user-controlled URL.
  2. The URL is used to construct a PSR-7 Uri or Request.
  3. The host component contains CRLF or another header-unsafe character.
  4. The request is serialized into a raw HTTP/1.x message without an explicit Host header.
  5. The host is copied into the serialized Host header.
  6. The serialized request is written to the network or otherwise processed by software 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.

This is not the normal request-sending path used by guzzlehttp/guzzle. Applications using guzzlehttp/psr7 only through Guzzle's standard HTTP client APIs are not expected to be affected. Applications are most likely to be affected when they manually serialize PSR-7 requests, forward raw HTTP messages, or use custom transports, proxying, crawling, webhook delivery, or similar request-dispatch code that serializes requests without independently validating URI hosts and header data. In deployments involving HTTP/1.1 connection reuse, proxies, gateways, or load balancers, this malformed serialized request may also contribute to request smuggling or cache poisoning, depending on how downstream components parse the request.

Patches

The issue is patched in 2.10.2 and later. 1.x is end-of-life and will not receive a patch.

Workarounds

If you cannot upgrade immediately, 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:

if (preg_match('/[\x00-\x20\x7F]/', $untrustedUrl)) {
    throw new \InvalidArgumentException('Insecure URL detected');
}

Applications that manually serialize or forward requests should also ensure the final HTTP client, transport, or serializer rejects invalid URI and header data before writing requests to the network.

References

Severity

  • CVSS Score: 5.3 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


guzzlehttp/psr7: CRLF Injection in HTTP Start-Line Serialization

CVE-2026-55766 / GHSA-vm85-hxw5-5432

More information

Details

Impact

guzzlehttp/psr7 did not reject CR/LF characters in certain first-party HTTP start-line fields: the request method, protocol version, and response reason phrase. If an application placed attacker-controlled data into one of those fields and later serialized the PSR-7 message as raw HTTP/1.x, for example with Message::toString() or an equivalent serializer, the serialized message could contain attacker-controlled header lines. The issue can also be reached through Message::parseRequest() or Message::parseResponse() when malformed raw messages are parsed into first-party PSR-7 objects and then serialized again.

Creating or modifying a Request, Response, or other PSR-7 object alone is not sufficient. The issue requires the malformed message to be serialized and written to the network, forwarded, replayed, or otherwise processed by software that does not independently reject the malformed start line. This is not the normal request-sending path used by guzzlehttp/guzzle; applications using guzzlehttp/psr7 only through Guzzle's standard HTTP client APIs are not expected to be affected.

Applications are most likely to be affected when they manually serialize PSR-7 messages, forward raw HTTP messages, or use custom transports, proxying, crawling, webhook delivery, testing, or similar code. Depending on how downstream HTTP/1.1 components parse the serialized message, this may lead to header injection, response splitting, request smuggling, or cache poisoning.

Patches

The issue is patched in 2.12.1 and later. Starting in that release, guzzlehttp/psr7 rejects CR/LF characters in HTTP method, protocol version, and response reason phrase values before storing them in first-party message objects.

Workarounds

If you cannot upgrade immediately, reject CR/LF in untrusted method, protocol version, and reason phrase values before constructing or modifying PSR-7 messages.

Applications that parse, forward, replay, or serialize raw HTTP messages cannot work around the parser entry points by validating only after parsing. They should validate the raw start line before calling Message::parseRequest() or Message::parseResponse(), avoid reparsing untrusted raw messages, or upgrade. If an application runs with attacker-controlled synthetic $_SERVER values, validate REQUEST_METHOD and SERVER_PROTOCOL before calling ServerRequest::fromGlobals().

Severity

  • CVSS Score: 4.8 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

guzzle/psr7 (guzzlehttp/psr7)

v3.0.0

Compare Source

Added
  • Add DiagnosticValue::escape() to escape controls and malformed UTF-8 in diagnostics
  • Add GuzzleHttp\Psr7\Exception\TimeoutException for timed-out stream operations
  • Add GuzzleHttp\Psr7\Utils::redactUserInfoInString() to redact the userinfo of a raw URI string within text
  • Promote GuzzleHttp\Psr7\Rfc3986 to public API with isValid*() predicates and canonicalizeIpv6()
  • Add GuzzleHttp\Psr7\UriNormalizer::CANONICALIZE_IPV6_HOST to PRESERVING_NORMALIZATIONS
Changed
  • Require psr/http-message:^2.0 and add native parameter and return types
  • Require psr/http-factory:^1.1
  • Reject native PHP serialization of stream implementations
  • Preserve request method casing, except ServerRequest::fromGlobals() still uppercases
  • Reject empty arrays and non-string values as header values
  • Reject invalid uploaded file trees and invalid parsed body values
  • Reject uploaded file specs missing tmp_name, size, or error
  • Reject non-integer and negative uploaded file error values
  • Reject invalid stream/upload sizes, buffer high-water marks, and dropping-stream limits
  • Rewind seekable uploaded-file streams before copying in UploadedFile::moveTo()
  • Reject negative read() lengths across all stream implementations
  • Detect the + flag anywhere in a mode for Stream::isReadable()/isWritable()
  • Reject empty strings returned by PumpStream source callables
  • Discard buffered bytes on PumpStream close and detach
  • Restore the original stream position after Message::bodySummary()
  • Allow null for the Message::bodySummary() truncation length to use the default
  • Validate LimitStream offset/limit and track non-seekable offset by bytes skipped
  • Make FnStream close and detach terminal, calling close callbacks at most once
  • Suppress exceptions from FnStream close callbacks during destructor cleanup
  • Make CachingStream::close() idempotent, preserving remote cleanup after detach
  • Do not move the CachingStream cursor when a SEEK_END target on an unknown-size stream is rejected
  • Normalize multiple leading slashes in Uri::getPath() and origin-form request targets
  • Serialize authority-less file URIs with rootless paths without the // separator
  • Serialize authority-less file URIs with empty paths as file: instead of the unparseable file://
  • Remove dot segments above the root per RFC 3986, prefixing authority-less // paths with /.
  • Return a network-path reference from UriResolver::relativize() when an empty-path target requires one
  • Stop returning an empty reference from UriResolver::relativize() when it would inherit the base fragment
  • Stop throwing from UriResolver::relativize() when an equal-path target's last path segment contains a colon
  • Harden URI host validation (delimiters, backslashes, IPv6, embedded ports); require schemes to start with a letter
  • Validate Uri::fromParts() ports instead of casting them
  • Treat ports 80 and 443 as defaults for the ws and wss schemes
  • Use the ws and wss default ports in UriComparator::isCrossOrigin() port comparisons
  • Redact all non-empty URI userinfo in Utils::redactUserInfo()
  • Rebuild server request URIs from $_SERVER by REQUEST_METHOD, using target authority before SERVER_PORT
  • Remove userinfo from absolute-form REQUEST_URI targets in ServerRequest::fromGlobals()
  • Reject zero-port HTTP_HOST and malformed SERVER_PORT in ServerRequest::getUriFromGlobals()
  • Reject malformed REQUEST_METHOD and SERVER_PROTOCOL server values in ServerRequest::fromGlobals()
  • Reject zero-port Host and normalize leading-zero ports in Message::parseRequest()
  • Reject duplicate Host headers and validate present values for all request-target forms
  • Reject zero-port, hostless, and userinfo absolute-form request targets in Message::parseRequest()
  • Synchronize the Host header in Request::withUri() when the URI changes or Host is empty
  • Include the URI port in Host headers synthesized by Message::toString()
  • Validate the Host header synthesized by Message::toString() from the request URI
  • Include non-default URI ports in Host headers set by Utils::modifyRequest() URI changes
  • Accept OPTIONS * and CONNECT authority-form request targets in Message::parseRequest()
  • Hide credential-bearing URI, server, and cookie arguments in stack traces on PHP 8.2+
  • Reject malformed HTTP request/response start-lines
  • Unfold obsolete HTTP/1.0 line folding for all valid request method tokens
  • Reject empty and control-character request targets in Request::withRequestTarget()
  • Validate iterator chunks passed to Utils::streamFor()
  • Validate unsupported values passed to Query::build()
  • Reject non-finite float values in Query::build() and MultipartStream contents
  • Reject non-finite float values in iterator chunks passed to Utils::streamFor()
  • Utils::streamFor() now rejects non-string scalar bodies
  • Uri::withQueryValues() now rejects non-string values
  • Reject invalid Utils::modifyRequest() change values
  • Use PHP debug type names in type error messages
  • Changed Utils::copyToStream() to throw when destination streams cannot make progress
  • Throw TimeoutException from Stream read/write and Utils copy/hash/readLine on stream timeouts
  • Throw TimeoutException from AppendStream::read(), CachingStream::read(), and Utils::tryGetContents() on stream timeouts
  • Re-throw TimeoutException from InflateStream when the decoded source stream times out
  • Close the compressed source stream from InflateStream::close()
  • Return the number of bytes copied from Utils::copyToStream()
  • Throw OverflowException when stream byte counts or offsets exceed PHP_INT_MAX
  • Translate StreamWrapper runtime failures to PHP stream failure values
  • Stop adding default Content-Length to multipart/form-data parts (RFC 7578 §4.8)
  • Escape multipart Content-Disposition parameters and reject unsafe boundaries and part headers
  • Preserve trailing whitespace in custom MultipartStream part header values
  • Preserve explicit custom MultipartStream boundary '0' instead of replacing it with a generated boundary
  • Made static utility classes non-instantiable
  • Validate bracketed IP-literal hosts consistently between parsing and withHost(), including userinfo forms
  • Percent-encode raw control bytes in userinfo before bracketed IP-literal hosts instead of parsing mutated values
  • Reject invalid UTF-8 and preserve percent-sequences in userinfo before bracketed IP-literal hosts
  • Normalize percent-encoded octets in the URI host to uppercase hex
  • Canonicalize IPv6 hosts to RFC 5952 form in Uri construction, fromParts(), and withHost()
  • Canonicalize bracketed IPv6 hosts in UriComparator::isCrossOrigin()
  • Reject malformed percent-sequences and percent-encoded bytes forbidden by the URI host policy
  • Extend CAPITALIZE_PERCENT_ENCODING and DECODE_UNRESERVED_CHARACTERS to userinfo and host
  • Trim header list elements with only spaces, horizontal tabs, and line terminators in Header::splitList()
  • Report header parameter PCRE failures explicitly in Header::parse()
  • Escape controls and malformed UTF-8 consistently in generated exception messages
Removed
  • Dropped support for PHP 7.2 and 7.3
  • Removed the ralouphie/getallheaders dependency
  • Removed deprecated Header::normalize() method

v2.13.0

Compare Source

Added
  • Add Utils:: asciiToLower, asciiToUpper, asciiUcFirst, caselessEquals, caselessContains
Changed
  • Use locale-independent ASCII case folding everywhere case is normalized
  • Trigger a runtime deprecation for previously deprecated functionality in 2.3.0

v2.12.5

Compare Source

Fixed
  • Compare header names and hosts with locale-independent ASCII lowercasing
  • Compare hosts without locale sensitivity when detecting cross-origin redirects

v2.12.4

Compare Source

Changed
  • Pass explicit trim characters ahead of the PHP 8.6 trim default change
Fixed
  • Anchor server port and response start-line patterns to the true end of input
  • Treat host-less origin-form request targets starting with // as paths in Message::parseRequest()
  • Reject raw DEL bytes in bracketed IP-literal hosts instead of parsing a mutated host
  • Reject invalid bytes after a bracketed IP-literal host instead of reparsing a different host

v2.12.3

Compare Source

Security

v2.12.2

Compare Source

Fixed
  • Report URI parsing, filtering, and normalization PCRE failures explicitly
  • Report HTTP message parser PCRE failures explicitly
  • Fail closed when PCRE validation fails for request targets and hosts

v2.12.1

Compare Source

Security

v2.12.0

Compare Source

Deprecated
  • Deprecated non-finite float values in Query::build() that guzzlehttp/psr7 3.0 rejects
  • Deprecated non-finite float multipart contents that guzzlehttp/psr7 3.0 rejects
  • Deprecated non-string scalar bodies in Utils::streamFor(); cast them to a string for 3.0
  • Deprecated non-string Uri::withQueryValues() values; cast them to a string for 3.0

v2.11.1

Compare Source

Fixed
  • Fixed non-finite float values emitting coercion warnings on PHP 8.5

v2.11.0

Compare Source

Changed
  • Changed Utils::modifyRequest() to reject conflicting URI and Host header changes in the same call
  • Changed Header::parse() to split semicolon-separated parameters without repeated regular expression lookaheads
  • Changed UriComparator::isCrossOrigin() so only HTTP and HTTPS missing ports receive implicit default ports
Deprecated
  • Deprecated invalid PSR-7 arguments that guzzlehttp/psr7 3.0 will require native types for
  • Deprecated non-string header values that guzzlehttp/psr7 3.0 will reject
  • Deprecated empty header value arrays that guzzlehttp/psr7 3.0 will reject
  • Deprecated URI schemes that do not match guzzlehttp/psr7 3.0 syntax requirements
  • Deprecated multipart boundary and custom part header metadata that guzzlehttp/psr7 3.0 will reject
  • Deprecated reliance on automatic uppercasing of request methods; guzzlehttp/psr7 3.0 preserves method casing
  • Deprecated invalid Utils::modifyRequest() change values that guzzlehttp/psr7 3.0 will reject
Fixed
  • Fixed Utils::copyToStream() to retry short destination writes instead of dropping the unwritten remainder
  • Fixed Header::parse() splitting of semicolon-separated parameters with escaped quotes

v2.10.4

Compare Source

Fixed
  • Apply UriNormalizer percent-encoding normalizations to URI fragments
  • Make LimitStream::getSize() return 0 for slices past the underlying stream end
  • Make AppendStream::read() return an empty string when no streams are attached
  • Make CachingStream::read() throw on an incomplete cache-target write instead of silently corrupting replays
  • Prevent CachingStream::seek() from looping indefinitely when the remote stream makes no progress

v2.10.3

Compare Source

Fixed
  • Fixed URI parsing for IPv6 literals containing embedded IPv4 addresses
  • Fixed malformed UTF-8 URI strings being parsed as empty URIs

v2.10.2

Compare Source

Security
Fixed
  • Make ServerRequest::fromGlobals() robust against unexpected HTTP header value types in $_SERVER

v2.10.1

Compare Source

Fixed
  • Fix Utils::modifyRequest() with numeric header names

v2.10.0

Compare Source

Changed
  • Harden ServerRequest::fromGlobals() against malformed $_SERVER values
  • Prevent custom stream metadata from affecting internal size handling
  • Throw when StreamWrapper::getResource() cannot create a resource
  • Preserve custom request implementations in Utils::modifyRequest()
  • Preserve custom URI implementations in UriResolver::resolve()
  • Make Uri::__toString() side-effect-free

v2.9.1

Compare Source

Fixed
  • Fix parsing of relative path references containing a colon in a non-initial path segment
  • Fix CachingStream::detach() returning an incomplete resource before the decorated stream has been fully read
  • Fix Message::bodySummary() returning null when truncating printable UTF-8 bodies inside a multibyte character

v2.9.0

Compare Source

Added
  • Added nested array expansion support to MultipartStream
  • Added @return static to MessageTrait methods
Changed
  • Updated MIME type mappings

v2.8.1

Compare Source

Fixed
  • Encode + signs in Uri::withQueryValue() and Uri::withQueryValues() to prevent them being interpreted as spaces

v2.8.0

Compare Source

Added
  • Allow empty lists as header values
Changed
  • PHP 8.5 support

v2.7.1

Compare Source

Fixed
  • Fixed uppercase IPv6 addresses in URI
Changed
  • Improve uploaded file error message

v2.7.0

Compare Source

Added
  • Add Utils::redactUserInfo() method
  • Add ability to encode bools as ints in Query::build

v2.6.3

Compare Source

Fixed
  • Make StreamWrapper::stream_stat() return false if inner stream's size is null
Changed
  • PHP 8.4 support

v2.6.2

Compare Source

Fixed
  • Fixed another issue with the fact that PHP transforms numeric strings in array keys to ints
Changed
  • Updated links in docs to their canonical versions
  • Replaced call_user_func* with native calls

v2.6.1

Compare Source

Fixed
  • Properly handle the fact that PHP transforms numeric strings in array keys to ints

v2.6.0

Compare Source

Changed
  • Updated the mime type map to add some new entries, fix a couple of invalid entries, and remove an invalid entry
  • Fallback to application/octet-stream if we are unable to guess the content type for a multipart file upload

v2.5.1

Compare Source

Fixed
  • Corrected mime type for .acc files to audio/aac
Changed
  • PHP 8.3 support

v2.5.0

Compare Source

Changed
  • Adjusted psr/http-message version constraint to ^1.1 || ^2.0

v2.4.5

Compare Source

Fixed
  • Prevent possible warnings on unset variables in ServerRequest::normalizeNestedFileSpec
  • Fixed Message::bodySummary when preg_match fails
  • Fixed header validation issue

v2.4.4

Compare Source

Changed
  • Removed the need for AllowDynamicProperties in LazyOpenStream

v2.4.3

Compare Source

Changed
  • Replaced sha1(uniqid()) by bin2hex(random_bytes(20))

v2.4.2

Compare Source

Fixed
  • Fixed erroneous behaviour when combining host and relative path

v2.4.1

Compare Source

Fixed
  • Rewind body before reading in Message::bodySummary

v2.4.0

Compare Source

Added
  • Added provisional PHP 8.2 support
  • Added UriComparator::isCrossOrigin method

v2.3.0

Compare Source

Fixed
  • Added Header::splitList method
  • Added Utils::tryGetContents method
  • Improved Stream::getContents method
  • Updated mimetype mappings

v2.2.2

Compare Source

Fixed
  • Fix Message::parseRequestUri for numeric headers
  • Re-wrap exceptions thrown in fread into runtime exceptions
  • Throw an exception when multipart options is misformatted

v2.2.1

Compare Source

Fixed
  • Correct header value validation

v2.2.0

Compare Source

Added
  • A more compressive list of mime types
  • Add JsonSerializable to Uri
  • Missing return types
Fixed
  • Bug MultipartStream no uri metadata
  • Bug MultipartStream with filename for data:// streams
  • Fixed new line handling in MultipartStream
  • Reduced RAM usage when copying streams
  • Updated parsing in Header::normalize()

v2.1.2

Compare Source

See change log for changes.

v2.1.1

Compare Source

Fixed
  • Validate header values properly

v2.1.0

Compare Source

Changed
  • Attempting to create a Uri object from a malformed URI will no longer throw a generic
    InvalidArgumentException, but rather a MalformedUriException, which inherits from the former
    for backwards compatibility. Callers relying on the exception being thrown to detect invalid
    URIs should catch the new exception.
Fixed
  • Return null in caching stream size if remote size is null

v2.0.0

Compare Source

Identical to the RC release.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
renovate Bot force-pushed the renovate/packagist-guzzlehttp-psr7-vulnerability branch from 8382c31 to 139e701 Compare June 24, 2026 23:33
@renovate
renovate Bot force-pushed the renovate/packagist-guzzlehttp-psr7-vulnerability branch 2 times, most recently from 1d5b50f to 19fde2c Compare July 18, 2026 11:35
@renovate
renovate Bot force-pushed the renovate/packagist-guzzlehttp-psr7-vulnerability branch from 19fde2c to 84c9f1d Compare July 24, 2026 07:45
@renovate renovate Bot changed the title Update dependency guzzlehttp/psr7 to v2 [SECURITY] Update dependency guzzlehttp/psr7 to v3 [SECURITY] Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

0 participants