如何保护您的服务器反对HTTPoxy漏洞

在2016年7月18日,一个CGI应用程序漏洞,被称为“HTTPoxy”,被披露。通过传递HTTP代理标头的请求,攻击者可以通过使HTTP请求的支持服务攻击脆弱的部署被重定向到一个任意web ...

什么是HTTPoxy?

在2016年7月18日,一个CGI应用程序漏洞,简称为HTTPoxy ,被披露。 攻击者可以通过传递一个HTTP攻击脆弱的部署Proxy头与他们的请求,这将改变联系后盾服务时使用的应用程序的URL。 这可以用于泄漏凭据,修改对应用程序的响应等。

该漏洞是由之间的名称冲突造成HTTP_PROXY环境变量,经常被用来指定后端代理服务的位置,并Proxy HTTP客户端头。 CGI规范要求客户端提供的报头被传递给用对环境HTTP_为命名空间的前缀。 这种混淆与冲突配置变量像HTTP_PROXY ,这也开始HTTP_ 如果CGI应用程序或库使用此变量而不进行其他处理,则可能会尝试使用客户端尝试连接代理服务时提供的值。

由于此漏洞影响各种类似CGI的实现,一些安全漏洞标识符已创建: CVE-2016-5386CVE-2016-5386CVE-2016-5387CVE-2016-5388CVE-2016- 1000109CVE-2016-1000110 (在写这篇文章的时候,这些被保留,但不填写)。

自2001年以来,HTTPoxy漏洞以某些形式已知,但直到最近才被认为是一个广泛的问题。 虽然它可能影响许多部署,缓解是相当简单和直接。

易受攻击的服务器和应用程序

HTTPoxy是许多CGI实现发现的一个常见漏洞。 应用程序或服务器可以正确地实现CGI规范并且仍然是脆弱的。

对于易受攻击的部署,它必须:

  • 使用HTTP_PROXY环境变量配置代理服务器连接 :无论是在应用程序代码本身或使用杠杆的库。 这是使用环境配置代理服务器的一个相当标准的方法。
  • 使用HTTP请求后端服务 :因为名称冲突是特定于HTTP_前缀,仅请求由应用使用HTTP将受到影响的。 使用HTTPS或任何其他协议的请求不容易受到攻击。
  • 工作在CGI或类似CGI的环境中 :其中客户端头被翻译成部署HTTP_前缀的环境变量是脆弱的。 任何兼容的CGI或相关协议(如FastCGI)的实现将会做到这一点。

正如您所看到的,部署是脆弱的,需要部署和特定于应用程序的因素的组合。 测试部署是否受到影响, 卢克Rehmann已经创建了一个简单的网站,以检查漏洞可公开访问的网站

语言特定信息

特别是PHP应用程序应该被审计,因为类似CGI的部署在PHP生态系统中比在其他语言中更常见。 此外,的广泛使用getenv在流行的库法放大了这个问题,因为它不是立即清楚,这将返回unsanitized用户的输入,而不仅仅是配置变量。 当前受影响的特定库是Guzzle(版本4.0.0rc2及更高版本),Artax和Composer的StreamContextBuilder类。

使用CGI部署时发现易受攻击的其他语言有Python和Go。 这些语言通常使用其他非易受攻击的方法部署。 然而,如果使用的CGI,即天真地读库HTTP_PROXY变量,而无需修改其行为是脆弱的。

如何击败漏洞

幸运的是,HTTPoxy是相对简单的修复。 可以从Web服务器层或应用程序或库解决此漏洞:

  • 应用程序或库可以忽略HTTP_PROXY ,当他们在一个CGI环境变量。
  • 应用程序或库可以使用不同的环境变量来配置代理连接
  • Web服务器或代理可以取消设置Proxy的客户端请求的接收的头

如果您使用的是易受攻击的库,则应该减轻服务器端的威胁,直到有可用的修补程序来解决该问题。 如果你是一个库或应用程序的作者和你的项目依赖于HTTP_PROXY变量配置代理后端,可以考虑使用替代变量在一个类似于CGI的环境中运行时,不会发生冲突。 Ruby和其他一些项目中使用CGI_HTTP_PROXY用于这一目的。

由于Proxy报头是不是一个标准的HTTP报头,它可以安全地在几乎所有的情况下被忽略。 这可以在用于将请求定向到应用程序本身的Web服务器或负载平衡器中完成。 因为Proxy HTTP头没有任何标准合法目的,它可以几乎总是被丢弃。

任何常见的Web服务器,负载平衡器或代理都可以取消设置相应的标头。

使用Apache删除HTTP代理头

如果您正在运行的Apache HTTP Web服务器, mod_headers模块可用于来取消所有请求头。

Ubuntu和Debian服务器

要启用mod_headers在Ubuntu或Debian的服务器,请键入:

sudo a2enmod headers

然后,打开全局配置文件:

sudo nano /etc/apache2/apache2.conf

朝向底部,添加:

/etc/apache2/apache2.conf
. . .
RequestHeader unset Proxy early

保存并关闭文件。

检查语法错误的配置:

sudo apache2ctl configtest

如果未报告语法错误,请重新启动服务:

sudo service apache2 restart

CentOS和Fedora服务器

mod_headers的模块应该默认为传统的安装启用。 取消设置Proxy头,打开全局配置文件:

sudo nano /etc/httpd/conf/httpd.conf

朝向底部,添加:

/etc/httpd/conf/httpd.conf
. . .
RequestHeader unset Proxy early

保存并在完成后关闭文件。

键入以下命令检查语法错误:

sudo apachectl configtest

如果未报告语法错误,请键入以下命令重新启动服务:

sudo service httpd restart

使用Nginx删除HTTP代理头

在Nginx中,缓解同样微不足道。 您可以轻松地对运行在服务器或上游的任何类CGI环境的环境进行清理。

Ubuntu和Debian服务器

在Ubuntu和Debian的服务器,FastCGI的参数通常包括无论从fastcgi_paramsfastcgi.conf建立FastCGI的代理文件时。 您可以取消设置HTTP_PROXY在这两个文件的标题:

echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi.conf
echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a  /etc/nginx/fastcgi_params

如果您在配置FastCGI代理时不采用其中一个文件,请务必在代理位置本身中包含相同的行:

/etc/nginx/sites-enabled/some_site.conf
. . .
    location ~ \.php$ {
        . . .
        fastcgi_param HTTP_PROXY "";
        . . .
    }
}

如果您正在使用Nginx的传统HTTP代理,您应该清除HTTP Proxy头为好。 HTTP代理标头中设置/etc/nginx/proxy_params文件。 您可以添加规则以取消设置Proxy头通过键入文件:

echo 'proxy_set_header Proxy "";' | sudo tee -a /etc/nginx/proxy_params

再次,如果您不是从您的服务器块配置中获取此文件,您必须将其添加到代理位置本身:

/etc/nginx/sites-enabled/some_site.conf
. . .
    location /application/ {
        . . .
        proxy_pass http://127.0.0.1;
        proxy_set_header Proxy "";
        . . .
    }
}

键入以下命令检查语法错误:

sudo nginx -t

如果没有报告错误,请重新启动服务:

sudo service nginx restart

CentOS和Fedora服务器

Nginx的在CentOS和Fedora还使用相同的fastcgi_paramsfastcgi.conf文件来配置FastCGI的代理。 取消设置HTTP_PROXY在这两个文件的标题中键入:

echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi.conf
echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a  /etc/nginx/fastcgi_params

如果在配置FastCGI代理时不采用其中一个文件,请务必在代理位置本身中包含同一行:

/etc/nginx/nginx.conf
. . .
    location ~ \.php$ {
        . . .
        fastcgi_param HTTP_PROXY "";
        . . .
    }
}

如果您正在使用Nginx的传统HTTP代理,您应该清除HTTP Proxy头为好。 你只需要添加一个规则取消设置Proxy ,你正在执行一个头在任何位置proxy_pass 如果你在哪里不确定proxy_pass正在使用,你可以轻松地搜索你的配置目录:

grep -r "proxy_pass" /etc/nginx
/etc/nginx/nginx.conf.default:        #    proxy_pass   http://127.0.0.1;

未注释掉(如上面的例子)任何结果应被编辑成包括proxy_set_header Proxy "";

/etc/nginx/nginx.conf
. . .
    location /application/ {
        . . .
        proxy_pass http://127.0.0.1;
        proxy_set_header Proxy "";
        . . .
    }
}

键入以下命令检查语法错误:

sudo nginx -t

如果没有报告错误,请重新启动服务:

sudo service nginx restart

使用HAProxy删除HTTP代理头

如果您正在使用HAProxy的指挥交通到您的应用服务器,你可以删除Proxy转发流量前头。

打开/etc/haproxy/haproxy.cfg文件进行编辑:

sudo nano /etc/haproxy/haproxy.cfg

您可以设置http-request指令在frontendbackend ,或者listen你的配置部分。

/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
    . . .

这些不需要在每个部分设置,但它不会伤害包括它们。 保存并在完成后关闭文件。

键入以下内容检查语法:

sudo haproxy -c -f /etc/haproxy/haproxy.cfg

如果没有找到问题,请键入以下命令重新启动服务:

sudo service haproxy restart

结论

HTTPoxy漏洞已经开放了很长时间,并且可能影响部署在Web上的大量应用程序。 幸运的是,它很容易修复使用任何Web服务器本机的头更改功能。