2016 年 7 月 18 日,一个名为“HTTPoxy”的漏洞被公布,影响一些在 CGI 或类 CGI 环境中运行的服务器端 Web应用,例如一些 FastCGI 配置。 目前已知受影响的语言包括 PHP、Python 和 Go。
已分配了许多 CVE,涵盖特定语言和 CGI 实现:
有一个新的网站描述该漏洞,一个CERT 漏洞说明,以及一个关于发现该漏洞的描述。 Vend 的开源网络开发人员Dominic Scheirlinck的个人网站上有更多信息。
这篇文章描述了该漏洞,并解释了如何使用 NGINX 或 NGINX Plus 来阻止在您的服务器上利用该漏洞的尝试。
该漏洞是由于命名空间冲突而存在的。 CGI 或类似 FastCGI 的接口根据 HTTP 请求参数设置环境变量,这些变量可以覆盖用于配置应用的内部变量。
目前,已知的唯一利用该漏洞的方法是针对在 CGI 和类 CGI 环境中运行的 Web应用,这些应用程序使用某些 HTTP 客户端库向其他服务发出 HTTP 请求。 在这种情况下,攻击者可以将应用生成的内部请求重定向到他们选择的服务器,从而捕获请求中包含的任何秘密数据,如下所示。
您可以使用 NGINX 或 NGINX Plus 来识别并阻止利用此漏洞的尝试。 这样做可以有效地防止任何攻击,让您有时间审核和更新任何受影响的代码。
要了解此漏洞的工作原理以及如何保护您的网站免受此漏洞的侵害,需要了解 CGI 和类似 CGI 的接口如何设置环境变量以及如何通过环境变量配置某些应用库。
许多 Web应用平台使用 CGI 或类似 CGI 的接口将应用连接到 Web 服务器。 这些接口将 HTTP 请求中的标头转换为以HTTP_
为前缀的环境变量。 然后,应用可以通过检查其环境来查找请求标头的值(例如User-Agent
)。
客户端可以通过发送带有适当标头的请求在应用程序的环境中创建任意环境变量(以HTTP_
开头)。 例如,请求头Foo:
bar
变成环境变量HTTP_FOO=bar
。
一些平台提供了隐藏环境变量的抽象层,例如 PHP 的$_SERVER
全局变量。 然而,这些抽象是建立在标准 CGI 和 FastCGI 设置环境变量的实践之上的。
例如,在 FastCGI 模式下运行时,PHP应用可以按如下方式确定请求的User-Agent
标头:
// 两种方法都返回相同的结果$useragent = getenv( 'HTTP_USER_AGENT' );
$useragent = $_SERVER['HTTP_USER_AGENT'];
复杂的 Web应用从外部库中引入功能。 例如,有时应用需要向其他服务发出 HTTP 请求(以类似微服务的方式),并且它们可能会使用其中一个常见的第三方库来执行此操作。 这些库通常支持称为HTTP 代理的功能,它是用于中继 HTTP 请求的中介服务器。
配置此类库的一个简单方法是通过环境变量定义配置。 广泛使用的PHP Guzzle库部分由名为HTTP_PROXY
的环境变量配置,该变量设置为代理服务器的地址。 如果以这种方式设置HTTP_PROXY
,则库会将其生成的所有 HTTP 请求中继到代理服务器的地址。 Go 的net/http
包和 Python 的 Requests 模块也以相同的方式信任和解释HTTP_PROXY
环境变量。
第 2 项中描述的库在设计时并未考虑 CGI 或类似 CGI 的接口,并且它们信任的HTTP_PROXY
环境变量与第 1 项中讨论的 CGI 和 FastCGI 接口使用的HTTP_
命名空间重叠。
通过将HTTP_PROXY
环境变量的值设置为自己选择的地址,攻击者可以重定向并捕获应用生成的内部 HTTP 请求。 这些请求可能包含敏感信息,例如身份验证密钥和私人数据,并且可能泄露有关可利用的其他 API 和端点的信息。
攻击者可以通过发送带有Proxy
标头的请求来实现这一点,CGI 或 FastCGI 接口会乖乖地为该应用调用创建一个名为HTTP_PROXY
的环境变量。 请注意,只有包含虚假代理
标头的请求才会受到直接影响。
HTTPoxy 漏洞并不直接影响 NGINX,但可以使用 NGINX 和 NGINX Plus 来阻止基于此漏洞的攻击。
您可以使用 NGINX 通过将HTTP_PROXY
FastCGI 参数设置为空字符串来“清理”应用的输入。 这将从 FastCGI 请求中完全删除参数:
fastcgi_param HTTP_PROXY“”;
当将 HTTP 请求代理到上游应用时,最好将任何代理
标头设置为空字符串,以防上游应用在易受攻击的平台上运行:
proxy_set_header 代理“”;
代理
不是标准的 HTTP 标头,因此任何包含此标头的请求都可能被视为可疑。 您可以使用 NGINX 或 NGINX Plus 将这些可疑请求记录到专用访问日志中,此处名为badactor.log :
# 在 http{} context:log_format proxylog '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_proxy"';
# 使用 'proxylog' 格式记录带有代理标头的请求
access_log /var/log/nginx/badactor.log proxylog if=$http_proxy;
笔记: 在放置此access_log
指令的配置上下文中,它将覆盖 NGINX 配置中更高级别定义的任何访问日志记录。
NGINX 和 NGINX Plus 提供了一种监控和击败 HTTPoxy 攻击的有效方法。 使用上面描述的技术来保护您的应用,同时审核、更新和测试您的代码以消除漏洞。
如果您有任何疑问,请评论此文章 - 或者,如果您是 NGINX Plus 订阅者,请随时联系我们的支持团队寻求帮助。
“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”