VirtualPath
ライブラリはパスを正規化し、ファイル システムにクエリを実行せずにディレクトリ トラバーサル攻撃を防ぎます。
rayne/virtual-path
インストールするには、依存関係マネージャー Composer を使用することをお勧めします。
composer require rayne/virtual-path
VirtualPath
クラスは、ファイル システムをクエリせずに、入力を絶対virtual pathに正規化します。また、ディレクトリ トラバーサル攻撃も検出してフラグを立てます。
JailedPath
クラスは、 VirtualPath
利用して、実際のファイルの操作に使用できる安全なパスを構築します。正規化は、ユーザーが入力したパスの仮想ルートとして使用される、 jail
と呼ばれるパスを基準にして行われます。 JailedPath
ファイル システムをクエリしないため、ローカル、リモート、または架空のパスを操作するのに適しています。
詳細については、「実装の詳細」セクションをお読みください。
TL;DR疑わしい場合は、 JailedPath
クラスを使用してください。
JailedPath
この例では、Web サイト訪問者は、相対パスをGET
パラメーターとして指定することによって、ローカル ディレクトリ/test
から任意のファイルをダウンロードできます。ユーザーがディレクトリ トラバーサル攻撃によってディレクトリを離れることを防ぐために、 JailedPath
は仮想ルート ディレクトリとして/test
とともに使用されます。
<?php
use Rayne VirtualPath JailedPath ;
$ jailedPath = new JailedPath ( ' /test ' , $ _GET [ ' path ' ] ?? '' );
if ( $ jailedPath -> hasJailbreakAttempt ()) {
// Log jailbreak attempt, ban user, …
return ;
}
if ( is_file ( $ jailedPath -> getAbsolutePath ())) {
@ readfile ( $ jailedPath -> getAbsolutePath ());
}
次の表は、ユーザー定義のパスがどのように正規化されるか、およびそれらが仮想ルートに対してどのように解釈されるかを示しています。
ユーザー入力 | hasJailbreakAttempt() | getAbsolutePath() | getRelativePath() |
---|---|---|---|
空の文字列 | false | /test | 空の文字列 |
. | false | /test | 空の文字列 |
a.png/../b.png | false | /test/b.png | b.png |
/a/./b | false | /test/a/b | a/b |
.. | true | /test | 空の文字列 |
../example | true | /test/example | example |
../etc/passwd | true | /test/etc/passwd | etc/passwd |
配列 | true | /test | 空の文字列 |
VirtualPath
固定プレフィックスやJailedPath
のシュガー コーティングが必要ない場合は、パスの正規化に使用されるクラスであるVirtualPath
で十分です。 VirtualPath
入力を正規化し、信頼できるパス (先頭に/
が付く正規化されたパス) と信頼できないパス (おそらく悪意のあるユーザー入力の文字列表現) を提供します。
前の例は、 VirtualPath
のインスタンス ( (string)
キャスト可能) が仮想ルート ディレクトリに追加されるときに、 VirtualPath
を使用して簡単に再作成できます。
<?php
use Rayne VirtualPath VirtualPath ;
$ path = new VirtualPath ( $ _GET [ ' path ' ] ?? '' );
$ absolutePath = ' /test ' . $ path ;
使用シナリオによっては、元の入力が信頼できない場合でも、正規化された信頼できるパスを使用すると便利な場合があります。たとえば、相対パスを明示的にサポートし、ユーザーが誤ってvirtual pathの外のファイルにアクセスしようとしたときに疑わしい利益を得ることができる場合です。
注: VirtualPath
先頭に/
付けた正規化されたパスを返します。ファイルを操作する場合は、信頼できるパスをプレフィックスとして追加することをお勧めします (現在のセクションのコード例を参照)。そうしないと、ファイル システムのルートに関連するファイルが参照されてしまいます。プレフィックスの追加を忘れないようにするには、実際のファイルを操作するときに代わりにJailedPath
クラスを使用します。
入力 | isTrusted() | getTrustedPath() | getUntrustedPath() |
---|---|---|---|
配列 | false | / | 空の文字列 |
空の文字列 | true | / | 空の文字列 |
../articles | false | /articles | ../articles |
tags/../../articles | false | /articles | tags/../../articles |
tags/../articles | true | /articles | tags/../articles |
../etc/passwd | false | /etc/passwd | ../etc/passwd |
/etc/passwd | true | /etc/passwd | /etc/passwd |
etc/passwd | true | /etc/passwd | etc/passwd |
純粋な仮想正規化パスを使用すると、次のようなさまざまな利点があります。
パスの正規化はファイル システムにクエリを実行せずに行われます
virtual pathの範囲外のファイルに対してタイミング攻撃を偽造することは不可能です
ディレクトリのトラバーサルを特定のディレクトリとその子に制限するために、複雑な比較は必要ありません。
のみ.
、 ..
、 (
/
に正規化) および/
パスの正規化のために解釈されます。
他のライブラリに見られる予期せぬ情報漏洩~
拡張はありません
VirtualPath
の実装では、制御文字と Unicode は解釈、変更、削除されません。
一部のシステムでは、ディレクトリおよびファイル パスに制御文字を含めることが許可されています
制御文字の削除はライブラリの範囲外です
リポジトリのクローンを作成する
git clone https://github.com/rayne/virtual-path.git
開発依存関係をインストールする
composer install --dev
テストを実行する
composer test