PHP-FPMでcgi.fix_pathinfo=0は必要なのか

tr;dr

PHP 5.3.9以降なら必要ない。

はじめに

NginxでPHPを動かす場合、大抵PHP-FPMを使うと思います。その設定方法を説明するほとんどのサイトではphp.inicgi.fix_pathinfo=0と指定すべきとしています。

例えばHow To Install Linux, nginx, MySQL, PHP (LEMP) stack on Ubuntu 14.04 | DigitalOceanではデフォルトのcgi.fix_pathinfo=1が超危険と書かれています。

This is an extremely insecure setting because it tells PHP to attempt to execute the closest file it can find if a PHP file does not match exactly.

またUbuntuDebianのNginxの設定ファイル/etc/nginx/sites-available/defaultにも以下*1のように書かれており、やはりこの設定は必ずやらないといけないように思えます。

# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

なぜこの設定が必要なのかを調べてみました。

cgi.fix_pathinfo=0とするようになった経緯

cgi.fix_pathinfo=0とするようになったのはFastCGIを使った際に生じるセキュリティ上の問題*2が原因です。

例えば、ファイルのアップロードが可能なウェブサイトがあったとします。このサイトはアップロードされたファイルを

http://example.com/uploads/photo.jpg

のようなURLで公開します。アップロードできるファイルの拡張子.jpgなどに制限されています。ここで、

http://example.com/uploads/photo.jpg/foo.php

にアクセスがあった場合、FPMは/uploads/photo.jpg/というディレクトリ内のfoo.phpを実行しようとします。もちろんそのようなファイルはないので404が返るはずですが、cgi.fix_pathinfoが有効な場合(デフォルト有効)FPMは次に/uploads/photo.jpgPHPとして実行しようとします(/foo.phpはPATH_INFOとして扱われます)。

/uploads/にはだれでもファイルをアップロードできるので、拡張子をjpgとしたPHPファイルをアップロードされた場合はかなり問題です。

そこで、cgi.fix_pathinfoを無効にして前述の動作をさせないようにする対策が取られるようになりました。

security.limit_extensionsの導入

この問題はFPMが.php以外のファイルをPHPとして実行しないようにすれば発生しません。

PHP :: Request #55181 :: Enhance security by limiting the script extensionsecurity.limit_extensionsを導入してFPMが実行できる拡張子を制限することが提案され、2012年1月にリリースされたPHP 5.3.9からこの仕組みが導入されています。 security.limit_extensionsのデフォルト値は.phpです。したがって、PHP 5.3.9以降ではcgi.fix_pathinfoを無効にする必要はありません。

まとめ

PHP 5.3.9以降ではcgi.fix_pathinfo=0とする必要性はない。

例えば冒頭で紹介したサイトはUbuntu 14.04を対象としているのでcgi.fix_pathinfo=0とする必要性はない。

安全側に倒してcgi.fix_pathinfo=0としても問題ないが、cgi.fix_pathinfoを有効にすると嬉しい事があるので有効にする流れになればいいと思う。どう嬉しいのかは別エントリで述べる。

参考

#642995 - Security issue with Nginx + PHP via FastCGI - Debian Bug report logs

http://cnedelcu.blogspot.jp/2010/05/nginx-php-via-fastcgi-important.html

*1:ちなみにこの文言はhttp://nginx.org/で配布されているNginxには書かれていません。

*2:2010年5月にnginx文件类型错误解析漏洞 - 80secで報告されたものです。