web-dev-qa-db-ja.com

Nginxでcgi.fix_pathinfoをまだ「危険」にしていますか?

この記事 in digitalocean.com Justin Ellingwoodは、オフにすることをお勧めしますcgi.fix_pathinfo

内部では、cgi.fix_pathinfoの動作を構成するセクションを見つける必要があります。コメントアウトされ、デフォルトで「1」に設定されます。これをコメント解除して「0」に設定する必要があります。これにより、プロセスに渡されたファイルが見つからない場合、PHPがパスの一部を実行しようとするのを防ぎます。悪意のあるユーザーがこれを使用して任意のコードを実行する可能性があります。

IMHOジャスティンエリングウッドは文書を書くのがとても上手ですが、この一節全体が少し不明瞭だったと言わざるを得ません。

ジャスティンが推奨したようにこれを処理するために私は走った:

sed -i "s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g" /etc/php/*/fpm/php.ini

この記事は2016年4月に書かれたもので、多少「古い」データに基づいている可能性があります。 2018年1月もこの推奨事項が依然として重要であり、Nginxの構成は非常に動的である可能性があります。

今日まで、そこで推奨されている変更を行うことが本当に重要ですか?

5
Arcticooling

この変更自体は「クリティカル」とは言いませんが、セキュリティ上の影響があります。私はそのアドバイスが関連するようになってから根本的に変わったものは何も知りません-PHPの振る舞いは、セキュリティに影響があるとしても、後方互換性に強くなる傾向があります。たとえば、uploadというディレクトリに、サーバーにファイルをアップロードできるサーバーがあるとします。アップロードスクリプトは、悪意のあるPHPファイルをアップロードしないように、特定の拡張子(.pngなど)のファイルのみを許可するように注意しています。

次に、攻撃者として、PHP Shellをファイルに書き込んで、ファイルにevil.pngという名前を付けてアップロードします。アップロード時にhttp://example.com/upload/evil.pngにアクセスしますが、ファイルが.pngで終わっているので、nginxはphp-fcgiにリクエストをphp-fcgiにディスパッチせず、phpとして処理されることを発見します。

私がPATH_INFOを知っている攻撃者なら、次にhttp://example.com/upload/evil.png/index.phpを試してみます。サーバーがそのように構成されている場合は、PHPが実行されます(nginxは最後にindex.phpを参照するため)、PHPはパスまで移動しますディレクトリ(evil.png)ではなく、ファイルであるコンポーネントを見つけて実行しようとすると、シェルが実行されて勝ちます。

そうは言っても、NGINX構成でパスを事前に分割することでこれに対処するより良い方法があるため、PHPはファイルシステムをウォークしていません。

Neal Pooleの優れた 問題に関するブログ投稿 から:

# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ \.php$ {
   # Zero-day exploit defense.
   # http://forum.nginx.org/read.php?2,88845,page=3
   # Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
   # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine.  And then cross your fingers that you won't get hacked.
   try_files $uri =404;

   fastcgi_split_path_info ^(.+\.php)(/.+)$;
   include fastcgi_params;
   fastcgi_index index.php;
   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
   fastcgi_pass php;
}
3
David

PHPが最初に見つかったファイルからスクリプトを処理しているため、今でも危険を伴うようです。では、なぜデフォルトを_;cgi.fix_pathinfo=1_のままにしていたのでしょうか?

CGIはPHPから独立しており、独自の標準を持っています。CGI(Common Gateway Interface)は、アプリケーションとデータを通信する方法、リクエスト情報と本文を渡す方法をサーバーに指示するインターフェースです。入力から出力へ。Webサーバーは、プログラムをCGIとして実行するように構成できます。つまり、サーバーは要求データを特定のプログラムに転送します。これにより、NGinxは要求をPHPに渡します。

CGI標準と言えば、_PHP-FPM_開発者は、_PHP-FPM_ iniファイルex:_/etc/php/7.2/fpm/php.ini_に記載されているCGI標準に準拠する必要があります。

_; 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 its 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.
; http://php.net/cgi.fix-pathinfo
;cgi.fix_pathinfo=1
_

したがって、_Setting this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting of zero causes PHP to behave as before._というテキストで選択について説明していると思います。これが _PATH_INFO_ CGI Spec です。

2
KeitelDOG