小さなWebアプリケーションがあります。一部のファイルをアップロードする必要があるため、ファイル拡張子をホワイトリスト(tgz、jpg、png、pdf、zip、rar、txt、gif、py、c、rb)で確認します。さらに、md5でファイル名をハッシュ化します。ユーザーがファイル「exploit.php.jpg」をアップロードすると、ファイル名は「526a8f9f3497b5a69bc4523ba0c6aacd.jpg」に変更されます。
画像の場合、MIMEタイプの検証も、「getimagesize()」またはresize-functionもありません。そのため、exploit.jpgに名前が変更されたphpファイルをアップロードできます。
これは非常に危険なようでユーザーも知っていますが、このファイルがサーバー(/images/526a8f9f3497b5a69bc4523ba0c6aacd.jpg
)のどこにあるかはわかりますが、このファイルを.phpとして実行することはできません。
/images/526a8f9f3497b5a69bc4523ba0c6aacd.jpg%00
または/images/526a8f9f3497b5a69bc4523ba0c6aacd.php
などを開こうとすると、「ファイルが見つかりません」(.php)または「画像を表示できません」(jpg、gif)しか表示されません。
howであるかどうか誰もが知っていますか?
ホワイトリストを信用しないでください。バイパスされる可能性があります。
Content-type: image/jpeg; filename=exploit.php
攻撃者がファイルに直接アクセスできる場合、ファイルをハッシュしても保護されません。
<img src='http://yoursite.net/images/526a8f9f3497b5a69bc4523ba0c6aacd.jpg>
PHPスクリプトを作成して、ファイルを読み取り、コンテンツを変更せずにユーザーに送信することができます。このようにして、攻撃者はサーバー上のファイルを参照することはなく、サーバー側で悪用する可能性があります。アップロードはトリガーされません:
<?php
$filename = getFilenameFromDatabase();
// e.g: $DOCROOT/images/exploit.rb.exe.py.bat.scr.php.jpg
header("Content-type: image/jpeg");
readfile("$filename");
?>
必ずファイルへのパスをフィルタリングしてください。そうしないと、攻撃者がファイルの読み取りアクセス権を取得する可能性があります。
ファイルアップロードの脆弱性は、ローカルファイルインクルードバグと組み合わせて悪用され、サーバー側を攻撃する可能性があります。または、悪意のあるファイル(例:pdf)をアップロードして、管理者権限を持つエンドユーザーを攻撃することもできます。
あなたのアプローチは十分に合理的であるように見えますが、悪魔は常に詳細にあり、より堅牢な評価のためにソースコードまたは実行中のアプリケーションを確認するには、セキュリティの知識を持つ誰かが必要です。