こんにちは、かつコーチです。
今回は、Webアプリでよく実装する「ファイルアップロード機能」の安全性について紹介します。
「拡張子をチェックしているから大丈夫」と思っていても、実は見落としがあるかもしれません。
なぜ拡張子チェックだけでは不十分なのか
二重拡張子で回避されることがある
たとえばimage.php.jpgのようなファイル名を使い、サーバー側の設定によっては意図せずPHPとして実行されてしまうケースがあります。
拡張子の文字列だけを見た単純なチェックでは、こうしたパターンを見抜けないことがあります。
Content-Typeは偽装できる
アップロード時に送られてくるContent-Typeヘッダーは、クライアント側(ブラウザや送信ツール)が指定する値であり、サーバー側で信頼しきれる情報ではありません。
「画像形式と表示されているから安全」とは言い切れないのです。
安全な実装の基本
1. 許可リスト方式でチェックする
「危険な拡張子を拒否する」のではなく、「許可する拡張子だけを通す」許可リスト方式が基本です。
画像アップロードであれば、jpg, jpeg, png, gif, webpなど、想定する形式だけを明示的に許可します。
2. ファイルの中身(マジックバイト)を検証する
拡張子やContent-Typeだけでなく、ファイルの先頭バイト列(マジックバイト)を見て、実際にその形式のファイルかどうかを確認します。
PHPであれば、getimagesize()関数などを使って、画像として正しく読み込めるかを検証する方法があります。
<?php
$uploadedFile = $_FILES['image']['tmp_name'];
// getimagesize()が失敗する場合、画像として不正とみなす
$imageInfo = @getimagesize($uploadedFile);
if ($imageInfo === false) {
throw new \RuntimeException('不正なファイル形式です。');
}
$allowedTypes = [IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF, IMAGETYPE_WEBP];
if (!in_array($imageInfo[2], $allowedTypes, true)) {
throw new \RuntimeException('許可されていない画像形式です。');
}
3. 保存先でプログラムを実行できない構成にする
アップロードされたファイルを保存するディレクトリでは、PHPなどのスクリプトが実行されない設定にしておきます。
Webサーバーの設定(Apacheの.htaccessやNginxの設定)で、アップロード先ディレクトリでのスクリプト実行を無効化する、という対策が有効です。
4. ファイル名をそのまま使わず、ランダムな名前にリネームする
アップロードされた元のファイル名には、意図しない文字列やパスを含む悪意ある入力が紛れている可能性があります。
保存時には、サーバー側でランダムな文字列やUUIDを使ったファイル名に変更するのが安全です。
5. 可能であれば、アプリと別ドメイン・別ストレージで配信する
アップロードされたファイルを、アプリ本体とは別のドメイン(オブジェクトストレージ等)で配信する構成にすると、万が一不正なファイルが紛れ込んでも、アプリのCookieやセッションに影響しにくくなります。
よくあるつまずきポイント
つまずき①:フロントエンドのJavaScriptだけでチェックしている
入力フォームの段階でJavaScriptによる拡張子チェックを行っていても、それはあくまで利用者への親切な表示であり、セキュリティ対策にはなりません。
JavaScriptのチェックは外部から簡単に回避できるため、サーバー側での検証が必須です。
つまずき②:ファイルサイズの上限を設定し忘れる
サイズの大きいファイルを大量にアップロードされると、ディスク容量の圧迫やサーバー負荷増大につながります。
許可する拡張子だけでなく、最大ファイルサイズの制限もあわせて設定しておきましょう。
まとめ
- 拡張子チェックだけでは、二重拡張子やContent-Type偽装を見抜けないことがある
- 許可リスト方式+ファイルの中身の検証(マジックバイトチェック)を組み合わせるのが基本
- 保存先でスクリプトを実行できない設定、ランダムなファイル名へのリネームも重要な対策
- フロントエンドのチェックはサーバー側の代わりにはならない
これで「AIエージェントによる自動攻撃」「Docker APIの設定」「バックアップの復元確認」「ファイルアップロードの安全な実装」という4本の記事で、基本的な見直しポイントを一通り紹介しました。あわせてチェックしてみてください。

コメント