2011-11-16 9 views
4

$_GET['']リクエストをサニタイズする最善の方法は何ですか? 1つのディレクトリからのみファイルをダウンロードできるようにしたい。

$baseDir = "/home/html/xy.com/public_html/downloads/";  
$path = realpath($baseDir . $_GET['file']); 

次のステップは何ですか。ここで

+1

間違いなく '..'を許可しないでください。 –

+0

これはすべてですか?その後、私のスクリプトは安全ですか? – Adrian

+0

いいえ、 '/'とファイルには含まれない他の文字を禁止します。 – jli

答えて

13

は、私はあなたがそこに持っている行の後にどうなるのかです:

基本的に
if (dirname($path) === $baseDir) { 
    //Safe 
} 

http://php.net/dirname

、ファイルはあなたがサポートし、1回のパスで実際に何かを送信する前にチェックを行います。 dirname()は末尾のパス区切り文字を残さないため、ファイル名の前に独自の/を追加して($path)、$baseDir定義から削除する必要があります。

+0

パス内の "/"、 ".."などの文字を無効にする必要があります。ありがとうございました。 – Adrian

+3

@Adrianあなたが進める前に、これがどのように機能するのか本当に理解する必要があります。あなたのこのスクリプトは、あなたがしなければ危険にさらされる可能性があります。私の方法は、 '$ path'にあるファイルのパスが' $ baseDir'で指定されたパスと同じであることを保証します。誰かが '..'や'/'を使うと、それらのパスはもはやマッチしません。したがって、安全です。これを理解することが重要です。複数のディレクトリをチェックしていた場合、問題はもっと複雑になります。 – Brad

+0

+1はBradのコメントです。ファイルシステムへのアクセスに対して非常に不自然である必要があることを理解することが不可欠です。 – toon81

3

相対パスフラグメントが存在しないことを事後チェックするのではなく、すぐにストリッピングする方が簡単です。すでにそれはあなたのベースディレクトリから上方または下方に移動することができないことを保証

$baseDir = "/home/html/xy.com/public_html/downloads/";  
$path = realpath($baseDir . basename($_GET['file'])); 

:あなたは値をフェッチするときだけで、すぐにbasename()を使用しています。

+0

ありがとう、私はこれをBradのソリューションと組み合わせました。 :) – Adrian

+0

'../'が$ _GETに入力されたらどうなりますか? –

+0

@tazotoduaもしあなたが 'basename()'の使用に関する答えを読んでいたら? – mario

関連する問題