徳丸浩の日記[PR]EGセキュアソリューションズ株式会社はエンジニアを募集しています2014年1月10日金曜日Windows版PHPのbasename関数はドライブレターを除去しない場合があるWindows版PHPのbasename関数は、パス名にディレクトリセパレータ(「\」および「/」)がない場合、ドライブレター(「C:」など)を除去しないことが分かりました。期待通りの結果となります。ドライブレターが取り除かれないことになります。オープンされるようです。限ったわけではなく、d:ドライブなど他のドライブのルートディレクトリ上のファイルもオープン可能となります。以下の条件が全てそろった場合、アプリケーションの想定ディレクトリではなく、任意ドライブのルートディレクトリの任意ファイルにアクセスできることになります。ファイル名として、basename関数を通しただけのパス名を指定しているディレクトリの指定をしていない。以下の影響が考えられます。ルートディレクトリに重要情報があり、ファイル名を知る手段があれば、情報漏洩となる指定したファイルに書き込みができる場合、ルートディレクトリの任意ファイル名で書き込みができる(*1)と、これだけ見ると「そんなにありそうではないけど、該当する場合はやばくないか」と思われるかもしれませんが、この条件に該当するスクリプトは、このbasename関数の挙動がなくても脆弱である可能性が高いです。ディレクトリ修飾をしていないので、カレントディレクトリのPHPソースファイルにアクセスできる可能性が高い書き込みできるスクリプトの場合、任意内容のPHPスクリプトを外部から書き込むことにより、スクリプトインジェクションができてしまう拡張子の制限をしている場合など、脅威は減少しますが、いずれにせよ良くない書き方であるわけで、この機会にソースを見直しましょう。安全なウェブサイトの作り方改訂第6版によると、ディレクトリトラバーサル脆弱性の根本的解決策は以下のいずれかとなっています。外部からのパラメータでウェブサーバ内のファイル名を直接指定する実装を避ける。(3-(i)-a)ファイルを開く際は、固定のディレクトリを指定し、かつファイル名にディレクトリ名が含まれないようにする。(3-(i)-b)先に指摘した「該当するケース」は、3-(i)-bの「固定のディレクトリを指定し」ていない状態ですので、これを指定することで、この問題の影響を受けなくなります。下記は、安全なウェブサイトの作り方改訂第6版のP71から、ディレクトリトラバーサル脆弱性の修正例です。basename($file_name),'rb');fpassthru($fp);上記はWindowsに限った話ではなく、Unix/Linuxでも同じですので、この機会にディレクトリトラバーサル対策の見直しをお勧めします。#66395として報告済みで、既にリポジトリ上は修正されていますが、完全には対策されないと予想されます。安全なウェブサイトの作り方のようにアプリケーション側の正しい対応をお勧めします。Windowsのルートディレクトリに書き込むには高い権限が必要ですが、Windows版Apacheの場合、SYSTEM権限で動作するので、Apache上のPHPからルートディレクトリにファイルを書き込みできることを確認しています。PHP5.5.9にて改修されました。詳しくは「Windows版PHPのbasename関数がドライブレターを除去しない問題はPHP5.4.25/PHP5.5.9で改修された」を参照下さい。