使用NGINX缓解HTTPoxy漏洞

NGINX | 2016年7月18日

2016年7月18日,一个名为“HTTPoxy”的漏洞被披露。该漏洞会影响一些在CGI或类似CGI的环境(例如某些FastCGI配置)中运行的服务器端Web应用程序。目前已知受影响的语言包括PHP、Python和Go。

已分配多个CVE,涉及特定语言和CGI实现:

现已有一个介绍该漏洞的新网站、一份CERT漏洞说明,以及一篇关于该漏洞发现过程的介绍。更多信息可参阅Dominic Scheirlinck的个人网站。他是Vend的一名开源Web开发人员。

本文介绍了该漏洞,并说明如何使用NGINX或NGINX Plus阻止攻击者尝试在服务器上利用该漏洞。

该漏洞源于命名空间冲突。CGI或类似FastCGI的接口会根据HTTP请求参数设置环境变量,而这些环境变量可能会覆盖用于配置应用程序的内部变量。

目前,已知利用此漏洞的唯一方式针对的是在CGI及类似CGI的环境中运行,并使用特定HTTP客户端库向其他服务发出HTTP请求的Web应用程序。在这种情况下,攻击者可能会将应用程序生成的内部请求重定向到其指定的服务器,从而获取请求中包含的任何机密数据,如下所示。

HTTPoxy利用命名空间重叠访问服务器内部流量

可以使用NGINX或NGINX Plus识别并阻止利用此漏洞的企图。这样可以有效防范攻击,为审核和更新所有受影响的代码争取时间。

HTTPoxy漏洞的利用方式

要了解此漏洞的工作原理以及如何保护网站免受其影响,需要先了解CGI和类CGI接口如何设置环境变量,以及环境变量如何配置某些应用程序库。

1:CGI和类CGI接口定义名为HTTP_*的环境变量

许多Web应用平台使用CGI或类似CGI的接口将应用连接到Web服务器。这些接口会将HTTP请求中的标头转换为带有HTTP_前缀的环境变量。随后,应用可以通过检查其环境来查找请求标头(例如User-Agent)的值。

客户端可以通过发送包含相应标头的请求,在应用程序环境中创建任意环境变量(以HTTP_开头)。例如,请求标头Foo: bar会转换为环境变量HTTP_FOO=bar。

某些平台提供了隐藏环境变量的抽象层,例如PHP的$_SERVER全局变量。不过,这些抽象层仍基于CGI和FastCGI设置环境变量的标准做法。

例如,在FastCGI模式下运行时,PHP应用程序可以按如下方式确定请求的“User-Agent”标头:

// both methods return the same result$useragent = getenv( 'HTTP_USER_AGENT' );
$useragent = $_SERVER['HTTP_USER_AGENT'];

2:部分应用程序库通过环境变量进行配置

复杂的Web应用会从外部库引入功能。例如,应用有时需要以类似微服务的方式向其他服务发出HTTP请求,并可能使用某个常见的第三方库来实现。这些库通常支持一项名为“HTTP代理”的功能,即通过中间服务器转发HTTP请求。

配置此类库的一种简便方法是通过环境变量定义配置。广泛使用的PHP Guzzle库有一部分配置由名为HTTP_PROXY的环境变量指定,该变量设置为代理服务器的地址。如果按此方式设置HTTP_PROXY,该库会将其生成的所有HTTP请求转发到代理服务器的地址。Go的net/http包和Python的Requests模块也会以相同方式信任并解析HTTP_PROXY环境变量。

3:漏洞的性质

第2项所述的库在设计时并未考虑CGI或类似CGI的接口,并且这些库所信任的HTTP_PROXY环境变量与第1项所述的CGI和FastCGI接口所使用的HTTP_命名空间重叠。

攻击者可将HTTP_PROXY环境变量的值设置为其指定的地址,从而重定向并捕获应用程序生成的内部HTTP请求。这些请求可能包含身份验证密钥和私有数据等敏感信息,还可能泄露其他可被利用的API和端点信息。

攻击者可以通过发送带有Proxy标头的请求来实现这一点,CGI或FastCGI接口会为该次应用程序调用创建一个名为HTTP_PROXY的环境变量。请注意,只有包含伪造Proxy标头的请求会直接受到影响。

使用NGINX和NGINX Plus抵御攻击

HTTPoxy漏洞不会直接影响NGINX,但可以使用NGINX和NGINX Plus阻止利用此漏洞发起的攻击。

与上游FastCGI应用通信

可以将HTTP_PROXY FastCGI参数设置为空字符串,使用NGINX“清理”应用程序的输入。这样会从FastCGI请求中彻底移除该参数:

fastcgi_param HTTP_PROXY "";

HTTP流量的负载均衡与代理

将HTTP请求代理到上游应用时,建议将所有Proxy标头设置为空字符串,以防上游应用运行在存在漏洞的平台上:

proxy_set_header Proxy "";

检测漏洞利用尝试

Proxy不是标准HTTP标头,因此,任何包含此标头的请求都可视为可疑请求。可以使用NGINX或NGINX Plus将这些可疑请求记录到专用访问日志中,此处该日志名为badactor.log:

# define 'proxylog' format in the http{} context:log_format proxylog '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '"$http_proxy"';

# log requests with a Proxy header using the 'proxylog' format
access_log /var/log/nginx/badactor.log proxylog if=$http_proxy;

注意:在放置此access_log指令的配置上下文中,该指令会覆盖NGINX配置中更高级别定义的所有访问日志记录。

确保安全

NGINX和NGINX Plus提供了一种有效监控和抵御HTTPoxy攻击的方法。在审核、更新和测试代码以消除漏洞期间,请使用上述技术保护应用。

如有任何问题,请在本文下方留言;如果您是NGINX Plus订阅用户,也可随时联系我们的支持团队寻求帮助。


分享

关于作者

相关博客文章

NGINX Plus R26 正式发布
NGINX | 2022/02/15

NGINX Plus R26 正式发布

NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
NGINX | 2022/02/10

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击

gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
NGINX | 2021/09/13

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划

了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。

NGINX Plus R19 正式发布
NGINX | 2019/09/03

NGINX Plus R19 正式发布

NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。

NGINX现已正式加入F5
NGINX | 2019/05/09

NGINX现已正式加入F5

NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。

使用NGINX和NGINX Plus实现高性能缓存
NGINX | 2016/08/24

使用NGINX和NGINX Plus实现高性能缓存

我将介绍NGINX在内容缓存和性能方面的工作原理,并分享一些控制NGINX内容缓存方式的技巧。