httpoxy漏洞是一个刚暴露出来的漏洞,它针对 php、go、python 等语言的 cgi 应用的漏洞。它将apache等组件中用于代理http访问的字段名变换为“http_proxy”,再传递给对应的cgi来执行。如果cgi或者脚本中对外请求的组件依赖于“http_proxy”这个环境变量,那就中招了,会导致远程攻击。
www对于每一个上网的人都再熟悉不过了,www连接请求就是采用的代理。我们在浏览网页,下载数据(也可采用ftp协议)时就是用http代理。它通常绑定在代理服务器的80、3128、8080等端口上。
httpoxy漏洞是一个服务器端 web 应用漏洞,如果你没有在服务器端部署这些代码,则不用担心。但如果你正在运行着 php 或 cgi 程序,你应该马上封挡 proxy 头部!马上! 具体做法参见下面。
当一个利用了此漏洞的 http 客户端发起请求时,它通过你的 web 应用去代理请求别的 url,直接让你的服务器打开指定的远程地址及端口,浪费服务器的资源,替攻击者访问指定的资源
httpoxy漏洞非常容易利用。希望安全人员尽快扫描该漏洞并快速修复。
以下情况会存在安全漏洞:
代码运行在 cgi 上下文中,这样 http_proxy 就会变成一个真实的或模拟的环境变量 一个信任 http_proxy的 http 客户端,并且支持代理功能 该客户端会在请求内部发起一个 http(或 https)请求
下列情形是已经发现存在该缺陷的环境:
语言环境http 客户端php php-fpm mod_php guzzle 4+ artax python wsgiref.handlers.cgihandler twisted.web.twcgi.cgiscript requests go net/http/cgi net/http
肯定还有很多我们没有确定是否存在缺陷的语言和环境。
php
是否存在缺陷依赖于你的应用代码和 php 库,但是影响面看起来似乎非常广泛 只要在处理用户请求的过程中使用了一个带有该缺陷的库,就可能被利用 如果你使用了有该缺陷的库,该缺陷会影响任意 php 版本 甚至会影响到替代的 php 运行环境,比如部署在 fastcgi 模式下的 hhvm 确认影响 guzzle、artax 等库,可能还有很多很多的库也受影响 guzzle 4.0.0rc2 及其以后版本受影响,guzzle 3 及更低版本不受影响 其它的例子还有 composer 的 streamcontextbuilder 工具类
举个例子说,如果你在 drupal 中使用 guzzle 6 模块发起外发请求(比如请求一个天气 api),该模块发起的请求就存在这个 httpoxy 缺陷。
python
python 代码只有部署在 cgi 模式下才存在缺陷,一般来说,存在缺陷的代码会使用类似wsgiref.handlers.cgihandler 的 cgi 控制器 正常方式部署的 python web 应用不受影响(大多数人使用 wsgi 或 fastcgi,这两个不受影响),所以受到影响的 python 应用要比 php 少得多 wsgi 不受影响,因为 os.environ 不会受到 cgi 数据污染 存在缺陷的 requests 库必须信任和使用 os.environ['http_proxy'],并且不做内容检查go go 代码必须部署在 cgi 下才受影响。一般来说受到影响的代码会使用 net/http/cgi 包 像 python 一样,这并不是部署 go 为一个 web 应用的通常方式。所以受到影响的情形很少 相较而言,go 的 net/http/fcgi 包并不设置实际的环境变量,所以不受影响 存在缺陷的 net/http 版本需要在外发请求中信任并使用 http_proxy ,并不做内容检查马上修复
最好的修复方式是在他们攻击你的应用之前尽早封挡 proxy 请求头部。这很简单,也很安全。
说它安全是因为 ietf 没有定义 proxy 请求头部,也没有列在 iana 的消息头部注册中。这表明对该头部的使用是非标准的,甚至也不会临时用到 符合标准的 http 客户端和服务器绝不应该读取和发送这个头部 你可以从请求中去掉这个头部或者干脆整个封挡使用它的请求 你可以在上游没有发布补丁时自己来解决这个问题 当 http 请求进来时就检查它,这样可以一次性修复好许多存在缺陷的应用 在反向代理和应用防火墙之后的应用剔除 proxy 请求头部是安全的
如何封挡 proxy 请求头部依赖于你的配置。最容易的办法是在你的 web 应用防火墙上封挡该头部,或者直接在 apache 和 nginx 上做也行。以下是一些如何做的指导:
使用如下语句封挡传递给 php-fpm、php-pm 的请求头,这个语句可以放在 fastcgi.conf 或 fastcgi_param 中(视你使用了哪个配置文件):
fastcgi_param http_proxy "";
在 fastcgi 模式下,php 存在缺陷(但是大多数使用 nginx fastcgi 的其它语言则不受影响)。
对于 apache 受影响的具体程度,以及其它的 apache 软件项目,比如 tomcat ,推荐参考 apache 软件基金会的官方公告。以下是一些主要信息:
如果你在 apache http 服务器中使用 mod_cgi来运行 go 或 python 写的脚本,那么它们会受到影响(这里 http_proxy 环境变量是“真实的”)。而 mod_php 由于用于 php 脚本,也存在该缺陷。
如果你使用 mod_headers 模块,你可以通过下述配置在进一步处理请求前就 unset 掉 proxy 请求头部:
requestheader unset proxy early
如果你使用 mod_security 模块,你可以使用一个 secrule 规则来拒绝带有 proxy 请求头部的请求。下面是一个例子,要确保 secruleengine 打开了。你可以根据自己的情况调整。
secrule &request_headers:proxy "@gt 0" "id:1000005,log,deny,msg:'httpoxy denied'"
最后,如果你使用 apache traffic server 的话,它本身不受影响。不过你可以用它来剔除掉 proxy 请求头部,以保护其后面的其它服务。具体可以参考 asf 指导。
通过下述配置剔除该请求头部:
http-request del-header proxy
通过下述语句取消该头部,请将它放到已有的 vcl_recv 小节里面:
sub vcl_recv {[...]unset req.http.proxy;[...]}
使用如下语句移除该头部。把它放到已有的过滤器里面:
http protocol httpfilter {match request header remove "proxy"}
弹回包含 proxy 头部的请求。
创建一个 /path/to/deny-proxy.lua文件,让它对于 lighttpd 只读,内容如下:
if (lighty.request["proxy"] == nil) then return 0 else return 403 end
修改 lighttpd.conf 以加载 mod_magnet 模块,并运行如上 lua 代码:
server.modules += ( "mod_magnet" )magnet.attract-raw-url-to = ( "/path/to/deny-proxy.lua" )
从请求中剔除 proxy 头部。加入如下语句到 lighttpd.conf中:
req_header.remove "proxy";
用户端的修复不能解决该缺陷,所以不必费劲:
使用 unset($_server['http_proxy']) 并不会影响到 getenv() 返回的值,所以无用 使用 putenv('http_proxy=') 也没效果(putenv 只能影响到来自实际环境变量的值,而不是来自请求头部的)
2001 年 3 月
randal l. schwartz 在 libwww-perl 发现该缺陷并修复。
2001 年 4 月
cris bailiff 在 curl 中发现该缺陷并修复。
2012 年 7 月
在net::http 的 http_proxy 实现中, ruby 团队的 akira tanaka 发现了该缺陷
2013 年 11 月
在 nginx 邮件列表中提到了该缺陷。发现者 jonathan matthews 对此不太有把握,不过事实证明他是对的。
2015 年 2 月
stefan fritsch 在 apache httpd-dev 邮件列表中提到了它。
2016 年 7 月
vend 安全团队的 scott geary 发现了对该缺陷,并且它影响到了 php 等许多现代的编程语言和库。
所以,这个缺陷已经潜伏了许多年,许多人都在不同方面发现了它的存在,但是没有考虑到它对其它语言和库的影响。安全研究人员为此专门建立了一个网站: https://httpoxy.org/ ,可以在此发现更多内容。
原文发布时间:2017年3月24日
本文由:比特网发布,版权归属于原作者
原文链接:http://toutiao.secjia.com/httpoxy-vulnerability-remote-attack-php-python-applications
本文来自云栖社区合作伙伴安全加,了解相关信息可以关注安全加网站