guzzlehttp/psr7 didn't reject line breaks in a request's method, its protocol version, or a response's reason phrase. If your app puts untrusted data in one of those and then writes the message out as raw HTTP, an attacker can add header lines of their own.

Depending on what reads that raw message next, this can lead to header injection, response splitting, request smuggling or cache poisoning. See the Guzzle advisory.

Who is affected

Apps that build psr7 messages themselves and serialize them, for example with Message::toString(). That's most likely in proxies, custom transports, crawlers, webhook delivery, testing or replay tools. Parsing an untrusted raw message with Message::parseRequest() or Message::parseResponse() and then serializing it again is affected too.

Sending requests the normal way through Guzzle's HTTP client is not expected to be affected. Creating a Request or Response alone does nothing: the message has to be serialized and then sent, forwarded or processed by software that doesn't reject the malformed first line.

What to do

Update guzzlehttp/psr7 to 2.12.1. Until you can, Guzzle advises rejecting CR and LF characters in untrusted method, protocol version and reason phrase values before building messages. If you parse raw messages, check the raw first line before calling the parse methods. If your app builds requests from $_SERVER values an attacker can influence, check REQUEST_METHOD and SERVER_PROTOCOL before calling ServerRequest::fromGlobals().

Reported by Ilia Alshanetsky.