説明
アップロードされたファイルの名前、拡張子、MIMEタイプ、保存先を検証しないと、実行可能なファイルや危険な内容を保存されるおそれがあります。
想定される影響
Webシェルのアップロード、悪意あるファイルの配布、既存ファイルの上書きにつながる可能性があります。
対処方法
サーバーが生成したファイル名を使い、拡張子とMIMEタイプを許可リストで検証します。アップロード先ではファイルを実行できないようにします。
例
変更前
php
<?php
$target = 'uploads/' . basename($_FILES['uploaded']['name']);
move_uploaded_file($_FILES['uploaded']['tmp_name'], $target);
変更後
php
<?php
if ($_FILES['uploaded']['error'] === UPLOAD_ERR_OK
&& mime_content_type($_FILES['uploaded']['tmp_name']) === 'image/png') {
$target = '/var/app/uploads/' . bin2hex(random_bytes(16)) . '.png';
move_uploaded_file($_FILES['uploaded']['tmp_name'], $target);
}
解説:
- 変更前: 種類、拡張子、保存先を検証せずに、クライアントが指定したファイル名を使っています。
- 変更後: アップロードの状態と内容の種類を確認し、サーバーが生成した名前で、実行されない場所に保存します。
これはアップロード処理の一部です。実際のサービスでは、サイズを制限し、許可した形式の内容を検証して、保存の失敗も処理してください。/var/app/uploads/ のファイルをWebサーバーが実行できないよう、別途設定する必要があります。