httpoxy – vulnerabilidad de aplicación CGI para PHP, Go, Python y otros

Se ha bautizado como httpoxy a una vulnerabilidad presente en aplicaciones web del lado del servidor, en entornos CGI o similares a CGI, que tiene su origen en un conflicto en el espacio de nombres:

  • RFC 3875 (CGI): establece que el valor de la cabecera Proxy de una petición debe almacenarse en la variable de entorno HTTP_PROXY
  • HTTP_PROXY: variable de entorno utilizada habitualmente para configurar un proxy saliente

Esto permite al atacante espiar las solicitudes HTTP salientes de una aplicación web, obligar a la aplicación a hacer todas las peticiones a través de un host y puerto mailiciosos, y bloquear los recursos del mismo .  Algunos de los casos confirmados son:

Lenguaje

Entorno

Cliente HTTP

PHP

php-FPM

mod_php

Guzzle 4+

Artax

Python

wsgiref.handlers.CGIHandler

twisted.web.twcgi.CGIScript

requests

Go

net/http/cgi

net/http

Lo mejor opción para mitigar esta vulnerabilidad es bloquear la cabecera Proxy lo antes posible, antes de que lleguen a su aplicación. Esto se consigue configurando su dispositivo firewall de aplicaciones web (si usa alguno), o aplicando las siguientes medidas correctivas directamente en los servidores web:

Nginx / FastCGI

Utilice esta opción:
fastcgi_param HTTP_PROXY "";

Apache

Si utiliza mod_headers, añade esta directiva:
RequestHeader unset Proxy early
Si utiliza mod_security, utiliza esta SecRule:
SecRule &REQUEST_HEADERS:Proxy "@gt 0" "id:1000005,log,deny,msg:'httpoxy denied'"

HAProxy

La siguiente direcitva elimina la cabecera Proxy:
http-request del-header Proxy

Varnish

Añada esto a la sección vcl_recv existente:

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

OpenBSD relayd

Añada el siguiente código a un filtro existente:

http protocol httpfilter {
match request header remove "Proxy"
}

lighttpd (<= 1.4.40)

Cree el fichero /path/to/deny-proxy.lua para lighttpd con el siguiente contenido:

if (lighty.request["Proxy"] == nil) then return 0 else return 403 end

Modifique lighttpd.conf para cargar mod_magnet y ejecutar el código lua anterior:

server.modules += ( "mod_magnet" )
magnet.attract-raw-url-to = ( "/path/to/deny-proxy.lua" )

lighttpd2 (en desarrollo)

Añada lo siguiente a lighttpd.conf

req_header.remove "Proxy";

Microsoft IIS con PHP o cualquier framework CGI

Lance el siguiente comando (por consola):

appcmd set config /section:requestfiltering /+requestlimits.headerLimits.[header='proxy',sizelimit='0']

podrá encontrar appcmd en %systemroot%\system32\inetsrv directory)

Para borrar el valor de la cabecera, utilice la siguiente regla de reescritura de URL:

<system.webServer>

    <rewrite>

        <rules>

            <rule name=”Erase HTTP_PROXY” patternSyntax=”Wildcard”>

                <match url=”*.*” />

                <serverVariables>

                    <set name=”HTTP_PROXY” value=”” />

                </serverVariables>

                <action type=”None” />

            </rule>

        </rules>

    </rewrite>

</system.webServer>

PHP

No utilice las siguientes soluciones, porque NO funcionan:

unset($_SERVER['HTTP_PROXY'])
putenv ( 'HTTP_PROXY =')

Por último algunas recomendaciones:

  • No despliegue aplicaciones en entornos donde los datos CGI se combinen con variables de entorno.
  • Utilice CGI_HTTP_PROXY en lugar de HTTP_PROXY para configurar el proxy de las solicitudes internas.
  • No confíe en HTTP_PROXY bajo CGI; es más, desconfíe de cualquier variable de entorno HTTP_*.
  • Restrinja completamente las solicitudes de salida de la aplicación web a través de un firewall, permitiendo únicamente las estrictamente necesarias.
  • Utilice HTTPS para solicitudes internas. Las conexiones HTTPS no están afectadas por httpoxy.

Fuente: https://httpoxy.org/

Deja un comentario