如何保护服务器免受 HTTPoxy 漏洞攻击

HTTPoxy是什么?

2016 年 7 月 18 日,一个 CGI 应用程序漏洞被泄露,称为 HTTPoxy,攻击者可以通过将其请求的 HTTP Proxy 标题传输来利用易受攻击的部署,这会改变应用程序在联系支持服务时使用的 URL。

该漏洞是由HTTP_PROXY环境变量,通常用于指定后端代理服务的位置,和Proxy HTTP客户端标题之间的名称碰撞引起的。 CGI 规格要求客户端提供的标题以HTTP_命名前缀传递到环境中。

由于这种漏洞影响了各种类似CGI的实现,因此已经创建了一些安全漏洞标识符:CVE-2016-5386(http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2016-5385),CVE-2016-5386(http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5386),CVE-2016-5387(http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5387),CVE-2016-5388(http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5388),CVE-2016-1000109(http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-1000109),以及CVE-2016-1000110(http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-1000110)(在本文写作时,这些是保留的,但没有填写)。

HTTPoxy的漏洞自2001年以来以某些形式已知,但直到最近才被认为是一个普遍存在的问题。

脆弱的服务器和应用程序

HTTPoxy 是许多 CGI 实现中发现的一种普遍漏洞,应用程序或服务器可以正确地执行 CGI 规范,并且仍然易受攻击。

为了使部署易受攻击,它必须:

  • 使用HTTP_PROXY环境变量来配置代理连接:无论是在应用程序代码本身还是使用杠杆的任何库中。这是使用环境配置代理服务器的相当标准的方法。
  • 使用 HTTP 进行后端服务的请求:由于名称碰撞是特定的HTTP_前缀,只有使用 HTTP 的应用程序提出的请求才会受到影响。使用 HTTPS 或任何其他协议的请求不会受到伤害。

正如你所看到的,部署和应用程序特定的因素的组合是必要的,以便部署是易受攻击的。 为了测试您的部署是否受到影响, Luke Rehmann创建了一个简单的 网站检查公众可访问的网站的漏洞

语言具体信息

特别是PHP应用程序应该进行审核,因为CGI类型的部署在PHP生态系统中比其他语言更为常见。此外,在流行的图书馆中getenv方法的广泛使用加剧了这个问题,因为不清楚这会返回未经修复的用户输入,而不仅仅是配置变量。

使用 CGI 部署时发现其他语言易受攻击的是 Python 和 Go. 这些语言更常用其他非易受攻击的方法部署,但是,如果使用 CGI,则无知地读取HTTP_PROXY变量而不修改其行为的库易受攻击。

如何克服脆弱性

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

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

如果您是图书馆或应用程序的作者,并且您的项目依赖HTTP_PROXY变量来配置代理后端,请考虑使用在CGI类型环境中运行时不会碰撞的替代变量。

由于Proxy标题不是标准的HTTP标题,它可以在几乎所有情况下被安全地忽略,这可以在Web服务器或负载平衡器中进行,用于直接向应用程序发送请求,因为ProxyHTTP标题没有任何标准的合法目的,所以几乎总是可以放弃。

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

使用 Apache 删除 HTTP 代理标题

如果您正在运行Apache HTTP Web 服务器,则可以使用mod_headers模块来取消对所有请求的标题设置。

Ubuntu 和 Debian 服务器

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

1sudo a2enmod headers

然后打开全球配置文件:

1sudo nano /etc/apache2/apache2.conf

在底部,添加:

1[label /etc/apache2/apache2.conf]
2. . .
3RequestHeader unset Proxy early

保存并关闭文件。

检查语法错误的配置:

1sudo apache2ctl configtest

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

1sudo service apache2 restart

CentOS 和 Fedora 服务器

「mod_headers」模块在常规安装中应该默认启用。 若要卸载「Proxy」标题,请打开全球配置文件:

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

在底部,添加:

1[label /etc/httpd/conf/httpd.conf]
2. . .
3RequestHeader unset Proxy early

保存并关闭文件,当你完成。

通过键入检查语法错误:

1sudo apachectl configtest

如果没有报告语法错误,请通过键入以下方式重新启动服务:

1sudo service httpd restart

使用 Nginx 删除 HTTP 代理标题

在 Nginx 中,缓解同样是微不足道的,您可以很容易地为在服务器上或上游运行的任何 CGI 类型的环境清洁环境。

Ubuntu 和 Debian 服务器

在 Ubuntu 和 Debian 服务器上,FastCGI 参数通常是从fastcgi_paramsfastcgi.conf文件中包含的,当您设置一个 FastCGI 代理程序时。

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

如果您在配置 FastCGI 代理程序时没有从其中一个文件中获取源,请确保在代理位置本身中包含相同的行:

1[label /etc/nginx/sites-enabled/some_site.conf]
2. . .
3    location ~ \.php$ {
4        . . .
5        fastcgi_param HTTP_PROXY "";
6        . . .
7    }
8}

如果你正在使用 Nginx 用于传统的 HTTP 代理,你也应该清除 HTTP ‘Proxy’ 标题。 HTTP 代理标题设置在 `/etc/nginx/proxy_params’ 文件中。

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

再次,如果您没有从服务器封锁配置中获取此文件,则必须在代理位置中添加它:

1[label /etc/nginx/sites-enabled/some_site.conf]
2. . .
3    location /application/ {
4        . . .
5        proxy_pass http://127.0.0.1;
6        proxy_set_header Proxy "";
7        . . .
8    }
9}

通过键入检查语法错误:

1sudo nginx -t

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

1sudo service nginx restart

CentOS 和 Fedora 服务器

在 CentOS 和 Fedora 上,Nginx 还使用相同的fastcgi_paramsfastcgi.conf文件来配置 FastCGI 代理。

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

如果您在配置 FastCGI 代理程序时没有从其中一个文件中获取源,请确保在代理位置中包含相同的行:

1[label /etc/nginx/nginx.conf]
2. . .
3    location ~ \.php$ {
4        . . .
5        fastcgi_param HTTP_PROXY "";
6        . . .
7    }
8}

如果您正在使用 Nginx 进行常规 HTTP 代理,您也应该清除 HTTP Proxy 标题。您只需要添加一个规则,以在您正在执行proxy_pass 的任何位置卸载Proxy 标题。

1grep -r "proxy_pass" /etc/nginx
1[secondary_label Output]
2/etc/nginx/nginx.conf.default:        #    proxy_pass http://127.0.0.1;

未评论的任何结果(如上面的示例)都应该编辑以包含 proxy_set_header Proxy ";:

1[label /etc/nginx/nginx.conf]
2. . .
3    location /application/ {
4        . . .
5        proxy_pass http://127.0.0.1;
6        proxy_set_header Proxy "";
7        . . .
8    }
9}

通过键入检查语法错误:

1sudo nginx -t

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

1sudo service nginx restart

使用 HAProxy 删除 HTTP 代理标题

如果您正在使用 HAProxy 将流量导向您的应用程序服务器,您可以在传输流量之前放下Proxy标题。

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

1sudo nano /etc/haproxy/haproxy.cfg

您可以在配置的前端,后端倾听部分设置http-request指令。

 1[label /etc/haproxy/haproxy.cfg]
 2frontend www
 3    http-request del-header Proxy
 4    . . .
 5
 6backend web-backend
 7    http-request del-header Proxy
 8    . . .
 9
10listen appname 0.0.0.0:80
11    http-request del-header Proxy
12    . . .

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

通过键入检查语法:

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

如果没有发现任何问题,请通过键入重启服务:

1sudo service haproxy restart

结论

HTTPoxy 漏洞已经被曝光了很长一段时间,可能会影响在 Web 上部署的大量应用程序,幸运的是,它很容易用任何 Web 服务器的头部更改功能来修复。

Published At
Categories with 技术
comments powered by Disqus