Jul 20, 2016

How to Protect Your Linux Server Against the HTTPOXY Vulnerability

On July 18th, 2016, a CGI application vulnerability, referred to as HTTPoxy, was disclosed. An attacker can exploit vulnerable deployments by passing an HTTP Proxy header with their request, which will alter the URL used by the application when contacting backing services. This can be used to leak credentials, modify responses to the application, etc.





The vulnerability is caused by a name collision between the HTTP_PROXY environmental variable, frequently used to specify the location of a backend proxy service, and the Proxy HTTP client header. The CGI specification calls for client-provided headers to be passed to the environment with a HTTP_ prefix for namespacing. This mangling clashes with configuration variables like HTTP_PROXY, which also start with HTTP_. If a CGI application or a library uses this variable without additional processing, it could end up using the value provided by the client when attempting connections to the proxy service.

As this vulnerability impacts a variety of CGI-like implementations, a number of security vulnerability identifiers have been created: CVE-2016-5386, CVE-2016-5386, CVE-2016-5387, CVE-2016-5388, CVE-2016-1000109, and CVE-2016-1000110 (At the time of this writing, these are reserved, but not filled out).

The HTTPoxy vulnerability has been known in some forms since 2001, but never recognized as a widespread issue until recently. Although it may affect many deployments, mitigation is quite simple and straight forward.

Vulnerable Servers and Applications

HTTPoxy is a general vulnerability found by many CGI implementations. An application or server can correctly implement the CGI specification and still be vulnerable.

For a deployment to be vulnerable, it must:
  • Use the HTTP_PROXY environmental variable to configure proxy connections: Either in the application code itself or any libraries that are used leverages. This is a fairly standard method of configuring proxy servers using the environment.
  • Make requests to backend services using HTTP: Because the name collision is specific to the HTTP_ prefix, only requests made by the application using HTTP will be affected. Requests using HTTPS or any other protocols are not vulnerable.
  • Operate in a CGI or CGI-like environment: Deployments where client headers are translated into HTTP_ prefixed environmental variables are vulnerable. Any compliant implementation of CGI or related protocols like FastCGI will do this.
As you can see, a combination of deployment- and application-specific factors are necessary for a deployment to be vulnerable. To test whether your deployment is affected, Luke Rehmann has created a simple site to check publicly accessible sites for vulnerability.

 

Language Specific Information

PHP applications in particular should be audited, since CGI-like deployments are much more common in the PHP ecosystem than in other languages. Furthermore, the widespread usage of the getenv method in popular libraries amplifies this issue, as it is not immediately clear that this will return unsanitized user input, not just configuration variables. Specific libraries that are currently affected are Guzzle (version 4.0.0rc2 and greater), Artax, and Composer's StreamContextBuilder class.

Other languages that were found to be vulnerable when deployed using CGI were Python and Go. These languages are more commonly deployed using other, non-vulnerable methods. However, if CGI is used, libraries that naively read the HTTP_PROXY variable without modifying their behavior are vulnerable.

 

How to Defeat the Vulnerability

Fortunately, HTTPoxy is relatively simple to fix. The vulnerability can be addressed from the web server layer or the application or library:
  • Applications or libraries can ignore the HTTP_PROXY variable when they are in a CGI environment.
  • Applications or libraries can use a different environmental variable to configure proxy connections
  • Web servers or proxies can unset the Proxy header received in client requests
If you are using a vulnerable library, you should mitigate the threat on the server end until patches are available to address the issue. If you are a library or application author and your project relies on the HTTP_PROXY variable to configure a proxy backend, consider using an alternative variable that will not clash when running in a CGI-like environment. Ruby and some other projects use CGI_HTTP_PROXY for this purpose.

Since the Proxy header is not a standard HTTP header, it can be safely ignored in almost all cases. This can be done in the web server or load balancer used to direct requests to the application itself. Because the Proxy HTTP header does not have any standard legitimate purpose, it can almost always be dropped.
Any common web server, load balancer, or proxy can unset the appropriate headers.

 

Removing the HTTP Proxy Header with Apache

If you are running the Apache HTTP web server, the mod_headers module can be used to unset the header for all requests.

 

Ubuntu and Debian Servers

To enable mod_headers in Ubuntu or Debian servers, type:
  • sudo a2enmod headers
Afterwards, open the global configuration file:
  • sudo nano /etc/apache2/apache2.conf
Towards the bottom, add:
/etc/apache2/apache2.conf
. . .
RequestHeader unset Proxy early
Save and close the file.
Check the configuration for syntax errors:
  • sudo apache2ctl configtest
Restart the service if no syntax errors are reported:
  • sudo service apache2 restart


CentOS and Fedora Servers

The mod_headers module should be enabled by default for conventional installations. To unset the Proxy header, open the global configuration file:
  • sudo nano /etc/httpd/conf/httpd.conf
Towards the bottom, add:
/etc/httpd/conf/httpd.conf
. . .
RequestHeader unset Proxy early
Save and close the file when you are finished.
Check for syntax errors by typing:
  • sudo apachectl configtest
If no syntax errors are reported, restart the service by typing:
  • sudo service httpd restart

 

Removing the HTTP Proxy Header with Nginx

In Nginx, mitigation is similarly trivial. You can easily sanitize the environment for any CGI-like environment running on the server or upstream.

 

Ubuntu and Debian Servers

On Ubuntu and Debian servers, FastCGI parameters are typically included from either the fastcgi_params or fastcgi.conf files when setting up a FastCGI proxy. You can unset the HTTP_PROXY header in both of these files:
  • echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi.conf
  • echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi_params
If you are not sourcing one of files when configuring your FastCGI proxies, be sure to include this same line in the proxy location itself:
/etc/nginx/sites-enabled/some_site.conf
. . .
    location ~ \.php$ {
        . . .
        fastcgi_param HTTP_PROXY "";
        . . .
    }
}
If you are using Nginx for conventional HTTP proxying, you should clear the HTTP Proxy header as well. HTTP proxying headers are set in the /etc/nginx/proxy_params file. You can add the rule to unset the Proxy header to that file by typing:
  • echo 'proxy_set_header Proxy "";' | sudo tee -a /etc/nginx/proxy_params
Again, if you are not sourcing this file from within your server block configuration, you'll have to add it in the proxy location itself:
/etc/nginx/sites-enabled/some_site.conf
. . .
    location /application/ {
        . . .
        proxy_pass http://127.0.0.1;
        proxy_set_header Proxy "";
        . . .
    }
}
Check for syntax errors by typing:
  • sudo nginx -t
If no errors are reported, restart the service:
  • sudo service nginx restart

 

CentOS and Fedora Servers

Nginx on CentOS and Fedora also uses the same fastcgi_params and fastcgi.conf files to configure FastCGI proxying. Unset the HTTP_PROXY header in both of these files by typing:
  • echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi.conf
  • echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi_params
If you are not sourcing one of these files when configuring your FastCGI proxies, be sure to include this same line in the proxy location itself:
/etc/nginx/nginx.conf
. . .
    location ~ \.php$ {
        . . .
        fastcgi_param HTTP_PROXY "";
        . . .
    }
}
If you are using Nginx for conventional HTTP proxying, you should clear the HTTP Proxy header as well. You just need to add a rule to unset the Proxy header in any location where you are executing a proxy_pass. If you are unsure where proxy_pass is being used, you can easily search your configuration directory:
  • grep -r "proxy_pass" /etc/nginx
Output
/etc/nginx/nginx.conf.default: # proxy_pass http://127.0.0.1;
Any results that are not commented out (like the example above) should be edited to include proxy_set_header Proxy "";:
/etc/nginx/nginx.conf
. . .
    location /application/ {
        . . .
        proxy_pass http://127.0.0.1;
        proxy_set_header Proxy "";
        . . .
    }
}
Check for syntax errors by typing:
  • sudo nginx -t
If no errors are reported, restart the service:
  • sudo service nginx restart

 

Removing the HTTP Proxy Header with HAProxy

If you are using HAProxy to direct traffic to your application servers, you can drop the Proxy header before forwarding the traffic.
Open up the /etc/haproxy/haproxy.cfg file for editing:
  • sudo nano /etc/haproxy/haproxy.cfg
You can set the http-request directive in the frontend, backend, or listen sections of your configuration.
/etc/haproxy/haproxy.cfg
frontend www
    http-request del-header Proxy
    . . .

backend web-backend
    http-request del-header Proxy
    . . .

listen appname 0.0.0.0:80
    http-request del-header Proxy
    . . .





These do not need to be set in each of the sections, but it won't hurt to include them. Save and close the file when you are finished.
Check the syntax by typing:
  • sudo haproxy -c -f /etc/haproxy/haproxy.cfg
If no problems are found, restart the service by typing:
  • sudo service haproxy restart

 

Conclusion

The HTTPoxy vulnerability has been out in the open for quite a long time and may affect a large set of applications deployed on the web. Luckily, it is easy to fix using the header-altering capabilities native to any web server.

Post a Comment

 
TECH SUPPORT © 2012-2016