HTTPoxy: vulnerabilidad PHP y CGI (HTTP_PROXY)

Tenemos recién salida del horno una nueva vulnerabilidad (HTTPoxy) con caracter crítico que afecta a servidores web que sirven PHP y CGI principalmente, aunque afecta también a otros lenguajes de scripting. El origen del problema es la variable HTTP_PROXY.

El ataque consiste en enviar una petición HTTP que contenga en las cabeceras la información de un proxy controlado por un atacante. El servidor web recibe la petición y la procesa. El script CGI entonces lee el contenido de HTTP_PROXY y debido a la vulnerabilidad confunde esta variable con el HTTP_PROXY del propio sistema y la exporta a nivel de SO. A partir de ahí, cuando el script CGI genera peticiones HTTP las envía a través de este proxy malicioso permitiendo al atacante hacer un «man-in-the-middle» para todo el tráfico HTTP generado por el servidor.

Se han publicado los detalles de la vulnerabilidad en infinidad de sitios, podéis revisar por ejemplo la información que ofrece al respecto  o incluso el sitio web que se ha creado expresamente para informar de la vulnerabilidad.

Lo más importante sin duda es como mitigar o bloquear la vulnerabilidad lo antes posible así que os dejo el método para hacerlo en los principales servidores web/proxies:

Apache

Ya sea a nivel global en httpd.conf o a nivel de VirtualHost:

RequestHeader unset Proxy early

Nota: requiere el módulo mod_headers.

Apache + Mod_Security

Si se usa mod_security se puede añadir esta regla de filtrado:

SecRule &REQUEST_HEADERS:Proxy "@gt 0" "id:1000005,log,deny,msg:'httpoxy denied'"

HAProxy:

http-request del-header Proxy

NGINX y FastCGI

En el archivo de configuración de FastCGI (php-fpm):

fastcgi_param HTTP_PROXY "";

Varnish

sub vcl_recv {
    [...]
    unset req.http.proxy;
    [...]
}

Microsoft IIS

%systemroot%\system32\inetsrv\appcmd.exe set config /section:requestfiltering /+requestlimits.headerLimits.[header='proxy',sizelimit='0']

JBoss y Tomcat

Añadir un filtrado específico para las peticiones con la cabecera proxy:

package com.redhat.prodsec.web.filter;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebFilter;

/*
 *  This is a sample servlet filter to disallow requests with "Proxy" http header
 */
@WebFilter("/*")
public class ProxyHeaderFilter implements Filter {

    /**
     * @see Filter#destroy()
     */
    public void destroy() {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) req;
        Enumeration headerNames = httpRequest.getHeaderNames();


        if (headerNames != null) {
                while (headerNames.hasMoreElements()) {
                    String headerName = headerNames.nextElement();
                    if(headerName.equalsIgnoreCase("Proxy"))
                        ((HttpServletResponse) res).sendError(HttpServletResponse.SC_BAD_REQUEST);
                }
        }

        chain.doFilter(req, res);

    }

    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
    }

}

Después, compilar y colocar el jar resultante en WEB-INF/lib para activar el filtro.

# jar -cvf ProxyHeaderFilter.jar com