Описание
Configuring a proxy in a stream context might allow for CRLF injection in URIs
Summary
Configuring a proxy in a stream context might allow for CRLF injection in URIs, resulting in HTTP request smuggling attacks.
Details
When creating a stream using one of the available stream creation functions (e.g., fopen
, file
, file_get_contents
...), developers can specify a custom stream context containing a set of parameters to use during the connection. One such parameter, in the case of HTTP and FTP streams, is proxy
. The HTTP context options also include a request_fulluri
boolean, which is required by some proxies to correctly forward the request.
While a normal request to http://example.com/path/to/file?query
would results in the following HTTP request:
when setting request_fulluri
to true
we obtain:
The vulnerability lies in the implementation of request_fulluri
, which just inserts the raw URI into the HTTP request line. In particular, this bypasses the normal control characters sanitization usually performed when parsing the URL.
This means that, if the resource URI is under the partial control of an attacker, when the request_fulluri
context parameter is true, a malicious actor could inject CRLF characters to perform a HTTP request smuggling attack.
Furthermore, if a non-HTTP stream sets a proxy
parameter in the context (right now only the FTP context supports this), the request_fulluri
parameter gets automatically silently enabled without the developer ever knowing.
Notice that, in the case of HTTP streams, setting a proxy is not strictly necessary, as the real issue is the request_fulluri
parameter.
PoC
We can test the raw query performed by PHP by simply using netcat in listening mode (nc -lvnp 1337
).
When no proxy is configured, the malicious input is correctly sanitized (still producing an error due to the presence of unencoded spaces):
When using a proxy and setting request_fulluri
to true
, we get request smuggling:
This also happens with HTTP proxies on FTP, without the request_fulluri
parameter:
Impact
CLRF injection in the URI leads to Server Side Request Forgery attacks (SSRF), which allows an attacker to bypass security controls, access internal endpoints, and, since we control the Host:
header, potentially access different hosts or machines.
Crafted requests can use any HTTP method and set any header to any value, including sensitive headers like Authorization
, Cookie
, Origin
, or Referer
.
Moreover, in some setups, the attacker might be able to read the HTTP response of each of the smuggled request.
Пакеты
< 8.1.31
8.1.31
< 8.2.26
8.2.26
< 8.3.14
8.3.14
Связанные уязвимости
In PHP versions 8.1.* before 8.1.31, 8.2.* before 8.2.26, 8.3.* before 8.3.14, when using streams with configured proxy and "request_fulluri" option, the URI is not properly sanitized which can lead to HTTP request smuggling and allow the attacker to use the proxy to perform arbitrary HTTP requests originating from the server, thus potentially gaining access to resources not normally available to the external user.
In PHP versions 8.1.* before 8.1.31, 8.2.* before 8.2.26, 8.3.* before 8.3.14, when using streams with configured proxy and "request_fulluri" option, the URI is not properly sanitized which can lead to HTTP request smuggling and allow the attacker to use the proxy to perform arbitrary HTTP requests originating from the server, thus potentially gaining access to resources not normally available to the external user.
In PHP versions 8.1.* before 8.1.31, 8.2.* before 8.2.26, 8.3.* before 8.3.14, when using streams with configured proxy and "request_fulluri" option, the URI is not properly sanitized which can lead to HTTP request smuggling and allow the attacker to use the proxy to perform arbitrary HTTP requests originating from the server, thus potentially gaining access to resources not normally available to the external user.
In PHP versions 8.1.* before 8.1.31, 8.2.* before 8.2.26, 8.3.* before ...