HTTPoxy - CGI "HTTP_PROXY" variable name clash

Public Date: July 5, 2016, 14:02
Updated October 11, 2016, 07:45 - Chinese, Simplified French Japanese Korean
Resolved Status
Important Impact

Background Information

A vulnerability was discovered in how CGI scripts are used by Red Hat products that leverage PHP, Go, Python, and other scripting languages.

Several web servers, web frameworks and programming languages (most commonly in a CGI environment) will set the environmental variable “HTTP_PROXY” based on data from incoming requests (e.g. a request header called “Proxy” with user supplied data). The environmental variable “HTTP_PROXY” is used by numerous web client software packages to specify a remote proxy server to use for HTTP, and in some cases HTTPS requests. As a result when a web application runs it may be possible for an attacker to specify a proxy server which the application uses for subsequent outgoing requests, allowing a "Man-in-the-Middle" attack. This flaw has been given the name HTTPoxy .


CGI and Environment variables

The HTTP server uses a set of environment variables to pass information to the CGI script. Some of those environment variables are used to communicate certain aspects of the HTTP request, like the content type, the TCP port, the hostname, or request method (for example, GET or POST). There is a different set of environment variables, that the RFC calls "Protocol-Specific Meta-Variables", which are used to pass the values of HTTP headers to the CGI script. The mapping of HTTP headers to environment variables follows a standard procedure: the HTTP header name is converted to uppercase, "-" is replaced with "_", and "HTTP_" is prefixed.

For example, the "Cookie" header is passed using the "HTTP_COOKIE" environment variable and the "Proxy" header is passed using the "HTTP_PROXY" environment variable. Please note that the "Proxy" header is not an official standard header, nor is it in the provisional header registry. The "Proxy" header should not be used by any standards compliant applications or clients.

The HTTP_PROXY "system" environment variable

There is a common system environment variable called "HTTP_PROXY", which can be used to communicate the HTTP (and sometimes HTTPS) proxy settings for an outgoing HTTP proxy to an application. This variable has a completely different purpose and context to that of the HTTP server-script variable. Applications, language libraries, or scripting modules use this environment variable to configure their proxy for subsequent outgoing HTTP traffic.

CGI Standard

The Common Gateway Interface is a standard designed to allow HTTP web servers, like Apache or nginx, to interface with executable scripts or binaries in order to generate dynamic web pages. This standard is documented in RFC 3875 . CGI scripts can be written in various scripting languages, like PHP, Python, Perl, Ruby, or golang, but can also be compiled, binary files.

The HTTP server and CGI script interact in the following way:

1. The HTTP server receives and parses an HTTP request, and configures the necessary environment variables.
2. The HTTP server calls the CGI script, and passes any request data through the script's standard input.
3.The CGI script processes the environment variables and its input, and sends a response back to the HTTP server using the script's standard output.
4. The HTTP server sends the response generated by the CGI script back to the client.

The Problem: HTTP_PROXY name clash

A CGI script cannot distinguish between CGI's "Protocol-Specific Meta-Variable", containing the value of the HTTP request's "Proxy" header, and the "system" environment variable HTTP_PROXY, containing HTTP proxy settings. A CGI script, module, or library reads the "HTTP_PROXY" environment variable, and assumes that this contains the "system" HTTP proxy settings. The misinterpreted value then changes how new HTTP requests are dealt with by the CGI script (and any other scripts and programs it may call) made during the processing of the current HTTP request.

Take Action

All Red Hat customers using CGI scripts with PHP, Go, or Python are strongly recommended to apply mitigations to their systems. Details around impacted packages and Image versions, as well as recommended mitigations can be found under the Resolve tab.

Acknowledgments

Red Hat would like to thank Dominic Scheirlinck of VendHQ for reporting and assisting with this issue.

Red Hat Product Security has rated this update as having a security impact of Important .

To diagnose this vulnerability in your environment, see the Resolve tab.

Impacted Products

  • Red Hat Enterprise Linux 7.x
  • Red Hat Enterprise Application Platform 6.x

  • Red Hat Enterprise Web Server 2.x

  • Red Hat JBoss Web Server 3.x

  • Red Hat JBoss Core Services

  • Red Hat Software Collections

Attack description and impact

The Attack

The attack is fairly straight-forward. An attacker sends a specially crafted HTTP request to a vulnerable CGI script. The request contains a "Proxy" header with the hostname or IP address and port of an attacker-controlled proxy as its value. The HTTP server receives the request and, as part of the usual processing, converts the "Proxy" header and its value into the "HTTP_PROXY" meta-data variable before continuing by calling the CGI script. The CGI script then reads the HTTP_PROXY variable, but confuses it with the "system" variable used to communicate the settings for the outgoing HTTP proxy and configures itself to use the specified proxy. If the CGI script performs HTTP requests, those requests are then sent through the attacker-controlled proxy, allowing the attacker to "Man-in-the-Middle" all parts of the HTTP traffic.

The Impact and Criticality

CGI scripts are only susceptible to this vulnerability if they misinterpret the HTTP_PROXY variable AND send HTTP (or in some cases HTTPS) requests. The number of scripts doing both of these will be a smaller subset of general CGI scripts.

It is difficult to state global impact and criticality, because this depends on how CGI script behaves. A particularly bad scenario is a CGI script that performs sensitive tasks (for example, authenticating using a REST-style API). In this case, an attacker could re-direct all parts of the HTTP traffic between the CGI script and the (REST-style) HTTP server through the attacker-controlled proxy. This could lead to the disclosure of sensitive information contained within both request and response sent between the CGI script and HTTP server.

Additionally, the attacker could manipulate the request and response content. If the CGI script sends requests to an internal server that cannot be reached from the outside internet, the attacker's proxy could not communicate with the internal server and the attacker could not intercept the internal server's responses. However, the attacker could still intercept the CGI script's request and send back a fake response.

Diagnose

To diagnose the issue, temporarily install the following as a CGI script on your server and make it executable:


test.cgi:

#!/bin/sh
echo "Content-Type:text/plain"
echo ""
echo "HTTP_PROXY='$HTTP_PROXY'"
											

Then call the CGI script with a “Proxy:” request header:

curl -H ‘Proxy: AFFECTED’ http://my-server-name/cgi-bin/test.cgi
												

If you see the following output, your server is unaffected:

HTTP_PROXY="
													

If instead you see the following, or any other output, your server may be affected and you should apply one of the mitigations below:

HTTP_PROXY='AFFECTED'
														

Mitigation

For mitigation details, review the Knowledgebase article matching your impacted server:

HTTPoxy - Is my JBoss/tomcat affected?

HTTPoxy - Is my Apache mod_cgi affected?

HTTPoxy - Is my nginx affected?

HTTPoxy - Is my Apache mod_fcgid affected?

HTTPoxy - Is my PHP application affected?

HTTPoxy - Is my Go application affected?

Updates for Affected Products

Fixes for all impacted products were released on July 18, 2016.

Product Package Advisory/Update
Red Hat Enterprise Linux 5.x httpd RHSA-2016:1421
Red Hat Enterprise Linux 6.x httpd RHSA-2016:1421
Red Hat Enterprise Linux 6.x php RHSA-2016:1609
Red Hat Enterprise Linux 6.x python RHSA-2016:1626
Red Hat Enterprise Linux 6.x python-twisted-web RHSA-2016:1978
Red Hat Enterprise Linux 6.x tomcat6 RHSA-2016-2045
Red Hat Enterprise Linux 7.x golang RHSA-2016:1538
Red Hat Enterprise Linux 7.x httpd RHSA-2016:1422
Red Hat Enterprise Linux 7.x php RHSA-2016-1613
Red Hat Enterprise Linux 7.x python RHSA-2016:1626
Red Hat Enterprise Linux 7.x python-twisted-web RHSA-2016:1978
Red Hat Enterprise Linux 7.x tomcat RHSA-2016-2046
Red Hat Enterprise Application Platform 6.x httpd patches pending
Red Hat Enterprise Web Server 2.x httpd RHSA-2016-1649
Red Hat JBoss Web Server 3.x httpd (zip) RHSA-2016:1624
Red Hat JBoss Web Server 3.x httpd (rpm) RHSA-2016-1624
Red Hat Software Collections httpd24 RHSA-2016:1420
Red Hat Software Collections for Red Hat Enterprise Linux Server (v. 6) rh-php56-php, rh-php55-php, rh-php54-php RHSA-2016:1612, RHSA-2016:1611, RHSA-2016:1610
Red Hat Software Collections for Red Hat Enterprise Linux Server (v. 6) python27-python, python33-python, (rh-python34-python RHSA-2016:1628, RHSA-2016:1629 , RHSA-2016:1630
Red Hat Software Collections for Red Hat Enterprise Linux Server (v. 7) php54-php, php55-php, php56-php RHSA-2016:1610, RHSA-2016:1611, RHSA-2016:1612
Red Hat Software Collections for Red Hat Enterprise Linux Server (v. 7) python33-python, python27-python , rh-python34-python, rh-python35-python RHSA-2016:1629, RHSA-2016:1628 , RHSA-2016:1630, RHSA-2016:1627
Red Hat JBoss Core Services httpd24 (zip) RHSA-2016:1625
Red Hat JBoss Core Services httpd24 (rpm) RHSA-2016-1851

Comments