Press "Enter" to skip to content

Nginx + PHP CGI的一个可能的安全漏洞

现在普遍的Nginx + PHP cgi的做法是在配置文件中, 通过正则匹配(Nginx(PHP/fastcgi)的PATH_INFO问题)设置SCRIPT_FILENAME, 今天小顿发现了一个这种方式的安全漏洞.
比如, 有http://www.laruence.com/fake.jpg, 那么通过构造如下的URL, 就可以看到fake.jpg的二进制内容:

http://www.laruence.com/fake.jpg/foo.php

为什么会这样呢?
比如, 如下的nginx conf:

location ~ \.php($|/) {
	fastcgi_pass   127.0.0.1:9000;
	fastcgi_index  index.php;
	set $script    $uri;
	set $path_info "";
	if ($uri ~ "^(.+\.php)(/.*)") {
		set  $script     $1;
		set  $path_info  $2;
	}
	include       fastcgi_params;
	fastcgi_param SCRIPT_FILENAME   $document_root$script;
	fastcgi_param SCRIPT_NAME       $script;
	fastcgi_param PATH_INFO         $path_info;
}

通过正则匹配以后, SCRIPT_NAME会被设置为"fake.jpg/foo.php", 继而构造成SCRIPT_FILENAME传递个PHP CGI, 但是PHP又为什么会接受这样的参数, 并且把a.jpg解析呢?
这就要说到PHP的cgi SAPI中的参数, fix_pathinfo了:

; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.  PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is.  For more information on PATH_INFO, see the cgi specs.  Setting
; this to 1 will cause PHP CGI to fix it's paths to conform to the spec.  A setting
; of zero causes PHP to behave as before.  Default is 1.  You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
cgi.fix_pathinfo=1

如果开启了这个选项, 那么就会触发在PHP中的如下逻辑:

/*
 * if the file doesn't exist, try to extract PATH_INFO out
 * of it by stat'ing back through the '/'
 * this fixes url's like /info.php/test
 */
if (script_path_translated &&
	(script_path_translated_len = strlen(script_path_translated)) > 0 &&
	(script_path_translated[script_path_translated_len-1] == '/' ||
....//以下省略.

到这里, PHP会认为SCRIPT_FILENAME是fake.jpg, 而foo.php是PATH_INFO, 然后PHP就把fake.jpg当作一个PHP文件来解释执行... So...
这个隐患的危害用小顿的话来说, 是巨大的.
对于一些论坛来说, 如果上传一个图片(实际上是恶意的PHP脚本), 继而构造这样的访问请求...
所以, 大家如果有用这种服务器搭配的, 请排查, 如果有隐患, 请关闭fix_pathinfo(默认是开启的).
详细漏洞信息, 请移步小顿的BLOG: 80Sec
另: 我认为这个和Nginx没啥关系, 不属于Nginx的漏洞. 是配置的问题, 现在到处都在说是Nginx的Bug, 不妥不妥.

141 Comments

  1. Prestige park grove
    Prestige park grove July 7, 2023

    Thanks for this post. I like to real ur blogs about coding..

  2. easybuilder.pro
    easybuilder.pro June 14, 2019

    kinda cool

  3. website pijat
    website pijat January 5, 2019

    […] PS: 鸣谢laruence大牛在分析过程中给的帮助 […]
    现在普遍的Nginx + PHP cgi的做法是在配置文件中, 通过正则匹配(Nginx(PHP/fastcgi)的PATH_INFO问题)设置SCRIPT_FILENAME, 今天小顿发现了一个这种方式的安全漏洞.

  4. iklan pijat
    iklan pijat January 5, 2019

    […] PS: 鸣谢laruence大牛在分析过程中给的帮助 […]

  5. obat kuat manjur
    obat kuat manjur January 5, 2019

    […] PS: 鸣谢laruence大牛在分析过程中给的帮助 […]

  6. jasa renovasi rumah
    jasa renovasi rumah November 30, 2018

    sealing for a minimum of 3 days straight. Grids last for at least 30days or longer depending on if you mai

  7. Keperawanan
    Keperawanan November 9, 2018

    Thank for nginx subscribe last years

  8. pijat purwokerto
    pijat purwokerto October 28, 2018

    Amazing for beginner SEO concepts and how to utilize these for videos on your site.

  9. Prabowo subianto
    Prabowo subianto September 22, 2018

    correctly in Explorer but looks great in Chrome.
    Do you have any ideas to help fix this issue?

  10. Bangun rumah di surabaya
    Bangun rumah di surabaya July 23, 2018

    If you like your software packaged, Microsoft may soon have another alternative for you — and one that doesn’t force you to pretend you’re still a student.

  11. Jasa
    Jasa July 23, 2018

    Really amazing

  12. darron
    darron July 17, 2018

    您好,文章第一行,“通过正则匹配(Nginx(PHP/fastcgi)的PATH_INFO问题)”的跳转链接配错了。
    看了您两篇文章后,得出的结论就是处理PATH_INFO有两种方法:
    1. PHP来处理,但还是要nginx支持,需要配一个参数:
    fastcgi_param PATH_INFO $fastcgi_script_name;
    (虽然不知道为什么。。。)
    2. nginx来处理,但是需要把php的cgi.fix_pathinfo设置为0

  13. pijat panggilan jakarta
    pijat panggilan jakarta June 30, 2018

    Figyelem: A kérelmet nem sikerült megfelelően feldolgozni. Az érvényesítési kód érvénytelen.

  14. 最近发现的一个安全漏洞(Nginx + PHP CGI的一个可能的安全漏洞)和这个配置有关系,

  15. belen
    belen March 2, 2018

    真是太感谢了,解答了我一直纠结的问题,之前见过的某网站应该就是这样中招的

  16. cara kaya
    cara kaya February 20, 2018

    Thank for guide me

  17. Indonesia
    Indonesia October 6, 2017

    its really helpful

  18. 誠実★信用★顧客は至上
    当社の商品は絶対の自信が御座います
    商品数も大幅に増え、品質も大自信です
    品質がよい 価格が低い 実物写真 品質を重視
    正規品と同等品質のコピー品を低価でお客様に提供します
    ご注文を期待しています!

  19. nerf images we
    nerf images we February 15, 2016

    There could be some toys that are not waterproof,
    so you can wash these with wet cloth and detergent.
    Provide him with something to get on plus a few safe chew
    toys for chewing. Which is the best nerf images we gun There are
    many toys for example Smurfs and shining knights etc.
    There isn’t any doubt that educational toys are employed in schools to great effect.
    Outside of your home, toy storage boxes, chests and
    benches give a wealth of possibilities for establishments, like daycares and preschools.

  20. madu hutan asli
    madu hutan asli August 5, 2015

    What’s up colleagues, how is everything, and what you wish
    for to say about this article, in my view
    its actually amazing in favor of me.

  21. I’m really loving the theme/design of your weblog.
    Do you ever run into any browser compatibility problems? A few of
    my blog readers have complained about my site not operating
    correctly in Explorer but looks great in Chrome.
    Do you have any ideas to help fix this issue?

  22. […] 能做到这种PATH_INFO有两种方式,一种是使用php自带的cgi.fix_pathinfo,需要把这个配置打开,当然这里可能会有漏洞,请参照(Nginx + PHP CGI的一个可能的安全漏洞)。我这里讲述的是另外一种方案,即使用nginx自己的正则过滤机制,模拟需要的情况。 […]

  23. […] 如果路径不是真实存在,就rewrite到index.php脚本。据说这种方法需要pathinfo所以有一点性能问题,而且有一个安全问题,还没时间研究。 location / { if (!-e $request_filename){ rewrite ^/(.*) /index.php last; } } […]

  24. seo Stevenage
    seo Stevenage July 29, 2014

    Hi! I knhow this is kinda off topic but I was wondering which blog platform are you using for this site?
    I’m getting tired of WordPress because I’ve had problems with hackers and I’m looking at alternatives for another platform.
    I would be fantastic if you could point me in the direction of a good platform.
    Here is my web page seo Stevenage

  25. jual madu hutan asli
    jual madu hutan asli May 16, 2014

    I almost never drop remarks, but i did some searching and wound up here Nginx +
    PHP CGI的一个可能的安全漏洞 | 风雪之隅.
    And I do have some questions for you if you tend not to mind.
    Is it just me or does it look as if like a few of these comments come across like they
    are written by brain dead visitors? 😛 And,
    if you are posting on other online social sites, I would like to follow everything fresh you have to
    post. Could you make a list of all of all your shared
    pages like your Facebook page, twitter feed, or linkedin profile?

  26. grosse
    grosse May 14, 2014

    Les posts sont effectivement plaisants

  27. Jasa SEO
    Jasa SEO July 22, 2013

    Woah! I’m really enjoying the template/theme of this website. It’s
    simple, yet effective. A lot of times it’s challenging to get that “perfect balance” between user friendliness and visual appearance. I must say that you’ve done a awesome
    job with this. Additionally, the blog loads very
    quick for me on Chrome. Outstanding Blog!

  28. Jasa SEO
    Jasa SEO July 15, 2013

    Greetings! Very useful advice within this post!
    It’s the little changes that make the greatest changes. Thanks for sharing!

  29. […] 最近发现的一个安全漏洞(Nginx + PHP CGI的一个可能的安全漏洞)和这个配置有关系, 请大家务必在使用第二种配置的时候,关闭cgi.fix_pathinfo. […]

  30. Anonymous
    Anonymous September 13, 2011

    我试了,我的nginx/0.7.67版本没有这个问题

  31. […] [1]http://hi.baidu.com/yuange1975/blog/item/4c223031a6727eaf5edf0e46.html [2]http://www.laruence.com/2010/05/20/1495.html This was written by admin. Posted on Friday, May 21, 2010, at 12:51 pm. Filed under Exploit. […]

  32. Wiki
    Wiki April 1, 2011

    Wiki is a very useful page.

  33. DADSA
    DADSA March 22, 2011

    DASASDSA

  34. hosting
    hosting March 21, 2011

    This is awsome water text effect :())

  35. film izle
    film izle September 28, 2010

    thanks you , All are nice t-shirts the color combination is good.

  36. new era hats
    new era hats September 20, 2010

    Hi,verybody,I will come again.

  37. Anonymous
    Anonymous September 7, 2010

    if ($request_filename ~* (.*)\\.php) {
    set $php_url $1;
    }
    if (!-e $php_url.php) {
    return 403;
    }
    blog:blog.sina.com.cn/harleychen

  38. […] 最近发现的一个安全漏洞(Nginx + PHP CGI的一个可能的安全漏洞)和这个配置有关系, 请大家务必在使用第二种配置的时候,关闭cgi.fix_pathinfo. […]

  39. […] 最近发现的一个安全漏洞(Nginx + PHP CGI的一个可能的安全漏洞)和这个配置有关系, 请大家务必在使用第二种配置的时候,关闭cgi.fix_pathinfo. […]

  40. […] 最近发现的一个安全漏洞(Nginx + PHP CGI的一个可能的安全漏洞)和这个配置有关系, 请大家务必在使用第二种配置的时候,关闭cgi.fix_pathinfo. […]

  41. SerranoMaritza33
    SerranoMaritza33 July 27, 2010

    Following my own exploration, thousands of persons on our planet receive the personal loans from good banks. Therefore, there’s great possibilities to receive a car loan in all countries.

  42. Bander
    Bander June 21, 2010

    弱弱问一句:关闭cgi.fix_pathinfo为0 可否解决噢?

  43. 打听1下
    打听1下 June 10, 2010

    很严重的安全漏洞。

  44. […] ( $fastcgi_script_name ~ ..*/.*php ) { return 403; }  PS: 鸣谢laruence大 牛在分析过程中给的帮助转载自:http://www.80sec.com/nginx-securit.html日志信息 […]

  45. […] ( $fastcgi_script_name ~ ..*/.*php ) { return 403; }  PS: 鸣谢laruence大 牛在分析过程中给的帮助转载自:http://www.80sec.com/nginx-securit.html日志信息 […]

  46. […] ( $fastcgi_script_name ~ ..*/.*php ) { return 403; }  PS: 鸣谢laruence大 牛在分析过程中给的帮助转载自:http://www.80sec.com/nginx-securit.html日志信息 […]

  47. Free
    Free May 23, 2010

    This is ……(T)

  48. […] 从http://www.laruence.com/2010/05/20/1495.html看到的:nginx+fcgi+php可能会存在一个很严重的安全漏洞。使用nginx + fcgi跑PHP的童鞋注意了,据说已经有网站中招。 […]

  49. Bingo
    Bingo May 21, 2010

    http://wiki.nginx.org/NginxHttpFcgiModule#fastcgi_split_path_info
    图片上传的路径加上这个配置可能就可以了
    location ~ ^(.+\.jpe?g)(.*)$ {

    fastcgi_split_path_info ^(.+\.jpe?g)(.*)$;
    fastcgi_param SCRIPT_FILENAME /path/to/php$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;

    }

  50. Neaton
    Neaton May 21, 2010

    应该跟php-fpm的版本有关系,0.6以下除0.6以外的版本才受这个漏洞的影响,可以测试下。

  51. […] jQuery(document).ready(function($){if(navigator.platform=="iPad")return;jQuery("img").lazyload({effect:"fadeIn",placeholder:"http://www.shocr.com/wp-content/plugins/jquery-image-lazy-loading/images/grey.gif"});});Blinux首页在线手册手机访问订阅RSS关于Englishnginx文件类型错误解析漏洞 Blinux Post in Linux的大杂烩,Tags: nginx, 安全 21 五月 2010 0 google_ad_client="pub-0521178536912504";google_ad_slot="8160586556";google_ad_width=468;google_ad_height=60; 热烈欢迎您来到Blinux!强烈推荐你订阅本博客 猛击此链接 .漏洞介绍:nginx是一款高性能的web服务器,使用非常广泛,其不仅经常被用作反向代理,也可以非常好的支持PHP的运行。80sec发现其中存在一个较为严重的安全问题,默认情况下可能导致服务器错误的将任何类型的文件以PHP的方式进行解析,这将导致严重的安全问题,使得恶意的攻击者可能攻陷支持php的nginx服务器。漏洞分析:nginx默认以cgi的方式支持php的运行,譬如在配置文件当中可以以location ~ .php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; include fastcgi_params; }的方式支持对php的解析,location对请求进行选择的时候会使用URI环境变量进行选择,其中传递到后端Fastcgi的关键变量SCRIPT_FILENAME由nginx生成的$fastcgi_script_name决定,而通过分析可以看到$fastcgi_script_name是直接由URI环境变量控制的,这里就是产生问题的点。而为了较好的支持PATH_INFO的提取,在PHP的配置选项里存在cgi.fix_pathinfo选项,其目的是为了从SCRIPT_FILENAME里取出真正的脚本名。 那么假设存在一个http://www.80sec.com/80sec.jpg,我们以如下的方式去访问http://www.80sec.com/80sec.jpg/80sec.php将会得到一个URI/80sec.jpg/80sec.php经过location指令,该请求将会交给后端的fastcgi处理,nginx为其设置环境变量SCRIPT_FILENAME,内容为/scripts/80sec.jpg/80sec.php而在其他的webserver如lighttpd当中,我们发现其中的SCRIPT_FILENAME被正确的设置为/scripts/80sec.jpg所以不存在此问题。 后端的fastcgi在接受到该选项时,会根据fix_pathinfo配置决定是否对SCRIPT_FILENAME进行额外的处理,一般情况下如果不对fix_pathinfo进行设置将影响使用PATH_INFO进行路由选择的应用,所以该选项一般配置开启。Php通过该选项之后将查找其中真正的脚本文件名字,查找的方式也是查看文件是否存在,这个时候将分离出SCRIPT_FILENAME和PATH_INFO分别为/scripts/80sec.jpg和80sec.php最后,以/scripts/80sec.jpg作为此次请求需要执行的脚本,攻击者就可以实现让nginx以php来解析任何类型的文件了。POC: 访问一个nginx来支持php的站点,在一个任何资源的文件如robots.txt后面加上/80sec.php,这个时候你可以看到如下的区别:访问http://www.80sec.com/robots.txtHTTP/1.1 200 OK Server: nginx/0.6.32 Date: Thu, 20 May 2010 10:05:30 GMT Content-Type: text/plain Content-Length: 18 Last-Modified: Thu, 20 May 2010 06:26:34 GMT Connection: keep-alive Keep-Alive: timeout=20 Accept-Ranges: bytes访问访问http://www.80sec.com/robots.txt/80sec.phpHTTP/1.1 200 OK Server: nginx/0.6.32 Date: Thu, 20 May 2010 10:06:49 GMT Content-Type: text/html Transfer-Encoding: chunked Connection: keep-alive Keep-Alive: timeout=20 X-Powered-By: PHP/5.2.6其中的Content-Type的变化说明了后端负责解析的变化,该站点就可能存在漏洞。漏洞厂商:http://www.nginx.org解决方案:我们已经尝试联系官方,但是此前你可以通过以下的方式来减少损失关闭cgi.fix_pathinfo为0或者if ( $fastcgi_script_name ~ ..*/.*php ) { return 403; }PS: 鸣谢laruence大牛在分析过程中给的帮助nginx文件类型错误解析漏洞:http://www.80sec.com/nginx-securit.html原创文章,转载请注明: 转载自Blinux本文链接地址: nginx文件类型错误解析漏洞No input file specified. (2)php安全设置之open_basedir (0)nginx windows发行已久 (0)nginx 301重定向 (4)给网站根目录添加sgid权限 (7)关闭Linux服务器ping响应 (0)nginx 自定义404 500 502 错误页面 (0)nginx 重启命令 (0)nginx 虚拟主机 (0) « Prev:SSH证书让Putty免密码登陆Linux Leave a Reply Name Mail (will not be published) Website […]

  52. Anders
    Anders May 21, 2010

    其实,从这个常见的 nginx 配置上看,是有问题的,最好还是严格一些的好。。
    # if ($uri ~ “^(\w+\.php)(/.*)”) {
    # set $script $1;
    # set $path_info $2;
    # }

  53. […] 或者 if ( $fastcgi_script_name ~ ..*/.*php ) { return 403; } PS: 鸣谢laruence大 牛在分析过程中给的帮助转载自: […]

  54. scotoma
    scotoma May 21, 2010

    谢谢…这个转发到Nginx群里面的了,提醒各位SA修改下配置文件,确实有很大的危害.
    感谢博主

  55. MoXie
    MoXie May 21, 2010

    这让我想起Apache中FilesMatch的漏洞。
    FilesMatch “\.php”
    结果造成文件名中只要包含.php就当Php执行了。
    FilesMatch “\.php$” 这样才正确。

  56. 雪候鸟
    雪候鸟 May 20, 2010

    当当网发现此安全漏洞, 有谁认识当当的人么? 转发下, 让他们赶紧修复吧, 谢谢

  57. […] PHP中的PATH_INFO 2010-05-20 14:00:22 | PHP 一直没有理解$_SERVER['PATH_INFO']这个变量的意义,今天看了风雪之隅的一篇文章Nginx + PHP CGI的一个可能的安全漏洞之后才关注一下这个变量。 […]

Comments are closed.