alotoftalking がcgi.fix_pathinfo
に関連するセキュリティ問題についてありました= PHPオプションはNginxで使用されます(通常、PHP-FPM、高速CGI)。
その結果、デフォルトのnginx設定ファイルは次のように言っていました:
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
しかし、今では、「公式」のNginx wiki それを述べています PATH_INFOは、上記のPHPオプションを無効にすることなく、正しく処理できます。それで、何ですか?
cgi.fix_pathinfo
の機能を明確に説明できますか? ( 公式ドキュメントは言うだけです :「PATH_INFOの詳細については、CGI仕様を参照してください」)PATH_INFO
およびSCRIPT_FILENAME
変数で何をしますか?各ステップで問題を理解しようとしています。たとえば、なぜphp-fpm Unixソケットを使用するのか理解できません 回避できました この問題。
特定の質問に取り組みますが、PATH_INFOとは何かを誤解しているため、質問自体が少し間違っています。
最初の質問は「このパス情報ビジネスとは何ですか?」
パス情報は、URIのスクリプトの後にあります(スラッシュで始まる必要がありますが、?
で始まるクエリ引数の前で終わります)。 CGIに関するWikipediaの記事 の概要セクションの最後の段落は、うまくまとめています。 PATH_INFO
の下は「/ THIS/IS/PATH/INFO」です。
http://example.com/path/to/script.php/THIS/IS/PATH/INFO?query_args=foo
次の質問は、「PHPはPATH_INFO
とSCRIPT_FILENAME
が何であるかをどのように判断するのですか?」
PATH_INFO
もサポートしていなかったため、PATH_INFO
がSCRIPT_FILENAME
に変更されました。ケース。 PHPをテストするのに十分古いバージョンはありませんが、シバン全体としてSCRIPT_FILENAME
を認識したと思います: "/path/to/script.php/THIS/IS/PATH/上記の例のINFO "(通常はdocrootが前に付けられています)。PATH_INFO
に入れ、SCRIPT_FILENAME
が指す部分だけを取得します。要求されるスクリプト(もちろんdocrootが前に付けられます)。PATH_INFO
をサポートするようになったとき、古い動作に依存するスクリプトを実行しているユーザーが新しいPHPバージョンを実行できるように、新機能の構成設定を追加する必要がありました。そのため、設定スイッチさえあります。最初から組み込まれているはずです(「危険な」動作を伴う)。しかし、PHPはどのようにしてスクリプトのどの部分とそのパス情報を知るのでしょうか。 URIが次のような場合:
http://example.com/path/to/script.php/THIS/IS/PATH/INFO.php?q=foo
SCRIPT_FILENAME
が決定され、PATH_INFO
が残りを取得します。SCRIPT_FILENAME
は "/foo.jpg"(これもdocrootで始まる)を取得し、PATH_INFO
は "/nonexistent.php"を取得します。なぜ、どのように危険なのかが明確になりました。
NginxとApacheは、このトリックを使用してリクエストを防止するように構築または構成できます。これを行う方法の例は ser2372674の回答 に含まれています。 このブログ記事 は問題をうまく説明していますが、適切な解決策がありません。
ただし、最良の解決策は、PHP-FPMが正しく構成されていることを確認することです。これにより、ファイルが「.php」で終わっていない限り、ファイルが実行されることはありません。 PHP-FPMの最近のバージョン(〜5.3.9 +?)にはこれがデフォルトとして設定されているので、この危険はそれほど問題にはなりません。
PHP-FPMの最新バージョン(〜5.3.9 +?)を使用している場合、以下の安全な動作はすでにデフォルトなので、何もする必要はありません。
それ以外の場合は、php-fpmのwww.conf
ファイルを探します(多分/etc/php-fpm.d/www.conf
、システムによって異なります)。これがあることを確認してください:
security.limit_extensions = .php
繰り返しますが、最近では多くの場所でそれがデフォルトになっています。
これは、攻撃者が「.php」ファイルをWordPressアップロードフォルダにアップロードし、同じ手法を使用して実行することを妨げるものではないことに注意してください。それでも、アプリケーションのセキュリティを確保する必要があります。
基本的に、これがなければ、 'foo.jpg'のような名前のPHPコードを含むファイルをWebサーバーにアップロードできます。次に http://domain.tld/foo.jpg/nonexistent.php のように要求すると、Webサーバースタックは誤ってああ言うでしょう。これはPHPです。これを処理する必要があります。foo.jpg/ nonexistent.phpが見つからないため、foo.jpgにフォールバックし、phpコードとしてfoo.jpgを処理します。それはシステムを非常に簡単な侵入に開放するので危険です。たとえば、画像のアップロードを許可するWebアプリケーションは、バックドアをアップロードするためのツールになります。
Php-fpmをunixソケットで使用して回避することについて。 IMOそれは問題を解決しません。
Nginx wiki でセキュリティ対策として
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
ロケーションブロックに含まれています。他のチュートリアルでは
try_files $uri =404;
nginx wikiによれば、同じように動作するはずですが、問題が発生する可能性があります。これらのオプションを使用すると、cgi.fix_pathinfo=1
はもう問題にはなりません。詳細は here を参照してください。