IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    HTTPOXY漏洞说明

    Laruence发表于 2016-07-19 01:50:58
    love 0
    • 作者: Laruence( )
    • 本文地址: http://www.laruence.com/2016/07/19/3101.html
    • 转载请注明出处

    好久没写文章了, 博客都长草了, 早上起来本来想去上班, 一看这么大雨, 这要上路了不得堵死啊.

    再加上有同学对我昨天转发的微博HTTPOXY漏洞表示不理解, 问会不会影响普通应用, 于是就写篇文章介绍下, 等早高峰过了吧;)…..

    不过要注意的是, 这里我只是介绍PHP这个角度, 关于Go和Python等其他角度的,因为我也不是”很”懂,你们还是看原文吧 :)

    漏洞原文在这里, https://httpoxy.org/, 没看懂的一定都是英语没过6级的 :)

    这里有一个核心的背景是, 长久一来我们习惯了使用一个名为”HTTP_PROXY”的环境变量来设置我们的请求代理, 比如在命令行我们经常这么用:

    http_proxy=127.0.0.1:9999 wget http://www.laruence.com/
    

    通过设置一个http_proxy的环境变量, 让wget使用代理请求http://www.laruence.com/

    时间久了, 大家就都会习惯用http_proxy环境变量来作为代理, 支持这种设置环境变量的方式, 于是很多PHP的类库,或者你自己写的代码都会很有可能写下如下类似的代码:

    <?php
    $http_proxy = getenv("HTTP_PROXY");
    if ($http_proxy) {
        $context = array(
            'http' => array(
                'proxy' => $http_proxy,
                'request_fulluri' => true,
            ),
    
        );
        $s_context = stream_context_create($context);
    } else {
        $s_context = NULL;
    }
    $ret = file_get_contents("http://www.laruence.com/", false, $s_context);
    

    比如很多常见的类库:

    • Guzzle: https://github.com/guzzle/guzzle/blob/10a49d5e1b8729c5e05cbdbf475b38b7099eb35e/src/Client.php#L167
    • Artax: https://github.com/amphp/artax/blob/3e3eedafcecc82c3c86c3a00ca602b5efa9c2cfa/lib/HttpSocketPool.php#L26

    就有这种类似的写法.

    那么问题来了, 在CGI(RFC 3875)的模式的时候, 会把请求中的Header, 加上HTTP_ 前缀, 注册为环境变量, 所以如果你在Header中发送一个Proxy:xxxxxx, 那么PHP就会把他注册为HTTP_PROXY环境变量, 于是getenv(“HTTP_PROXY”)就变成可被控制的了. 那么如果你的所有类似的请求, 都会被代理到攻击者想要的地址,之后攻击者就可以伪造,监听,篡改你的请求了…

    比如:

     curl -H "Proxy:127.0.0.1:8000" http://host.com/httpoxy.php
    

    所以, 这个漏洞要影响你, 有几个核心前提是:

    • 你的服务会对外请求资源
    • 你的服务使用了HTTP_PROXY环境变量来代理你的请求(可能是你自己写,或是使用一些有缺陷的类库)
    • 你的服务跑在PHP的CGI模式下(cgi, php-fpm)

    如果你没有满足上面的条件, 那么恭喜你,你不受此次漏洞影响 :) .

    后记: 经过微博同学的提醒, 我可能把这个问题的影响潜意识的让大家觉得危害不大, 但实际上, 延伸一下: 所有HTTP_开头的环境变量在CGI下都是不可信的, 千万不要用于敏感操作, 另外一点就是, 我深刻的体会过, 做安全的同学想象力非常丰富, 虽然看似很小的一个点, 但到了安全的同学手里, 配合他们丰富的想象力, 强大的社工能力, 也是能做出巨大攻击效果的….

    那知道了原理修复起来也很简单了, 以Nginx为例, 在配置中加入:

       fastcgi_param HTTP_PROXY "";
    

    所以建议, 即使你不受此次漏洞影响, 也应该加入这个配置.

    而如果你是一个类库的作者,或者你因为什么原因没有办法修改服务配置, 那么你就需要在代码中加入对sapi的判断, 除非是cli模式, 否则永远不要相信http_proxy环境变量,

    <?php
    if (php_sapi_name() == 'cli' && getenv('HTTP_PROXY')) {
       //只有CLI模式下, HTTP_PROXY环境变量才是可控的
    }
    

    就好比Guzzle的这个修复:
    https://github.com/guzzle/guzzle/commit/9d521b23146cb6cedd772770a2617fd6cbdb1596#diff-ff73e042e738204c6da009e2ed19f783L166

    thanks


    Comments

    • 2016/07/19, Ethan writes: 感谢鸟哥!我们各种接口调用,又是nginx的,可能是高危群体了吧。
    • 2016/07/19, rambone writes: 这就是咱们鸟哥 第一时间 从前方发回报道
    • 2016/07/19, Axios writes: 还是鸟哥的博客看着舒服,比英文的好多啦~
    • 2016/07/19, guest writes: 各位Apache下php_mod不会收到影响吗?
    • 2016/07/19, Bun writes: 终于更新blog了,支持鸟哥,感谢鸟哥
    • 2016/07/19, windsor writes: 赞

    Copyright © 2010 风雪之隅 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)

    Related Posts:

    • 通过构造Hash冲突实现各种语言的拒绝服务攻击
    • 让你的PHP7更快(GCC PGO)
    • 在PHP中使用协程实现多任务调度
    • GCC优化引起的一个”问题”
    • Curl的毫秒超时的一个”Bug”
    • Weibo LAMP演变 – 6月在上海分享的PPT
    • 一个小玩意PHP-Valgrind的介绍
    • PHP浮点数的一个常见问题的解答
    • Yaf and Phalcon, which is faster?
    • Yar – 并行的RPC框架(Concurrent RPC framework)


沪ICP备19023445号-2号
友情链接