Shikata Ga Nai

Private? There is no such things.

ファイルアップロードの脆弱性はなぜ生まれるのか?その原因と見落としがちな落とし穴を解説!

Hello there, ('ω')ノ

✅ ファイルアップロード機能の危険性は理解されているはずなのに…

現代のWebアプリケーションにおいて、 「何でも自由にアップロードできる」 ようなサイトは滅多にありません。

しかし実際には、次のような理由で 「一見しっかり対策されているように見えても、簡単にバイパスされる」 脆弱性が多く存在しています。


🧨 ファイルアップロード脆弱性が発生する主な原因


1. ⚫ ブラックリスト方式の不完全な拡張子チェック

🔍 問題点

  • 開発者は .php, .exe, .jsp などの危険な拡張子だけをブロックしようとします。
  • これは ブラックリスト方式(除外方式) であり、見落としが起こりやすいです。

📚 攻撃のバイパス例

  • .php がブロックされても、.php5.pHp は通ってしまうケースがある。
  • .jpg.php(二重拡張子)なども、多くのサーバーで 後ろの拡張子だけが解釈される

ポイント:ブラックリストは抜け道だらけ!


2. 🖼️ MIMEタイプやContent-Typeの信頼

🔍 問題点

  • サーバーがファイルの種類を Content-Type: image/jpeg などのヘッダーに頼って判別している場合、 Burp Suiteなどのツールで簡単に偽装可能

📚 攻撃者のやり方

  • .php ファイルに "Content-Type: image/jpeg" を付けて送信
  • サーバー側がその値だけを信じると、画像として受け入れてしまう

ポイントContent-Typeはクライアント側の自己申告であり、信頼してはいけない!


3. 🔄 ファイル検証の一貫性の欠如

🔍 問題点

  • 同じアプリケーション内で、アップロード時の検証とアクセス時の挙動が異なることがある。
  • 例えば:

    • アップロードエンドポイントではチェックしているが、別のディレクトリで実行可能
    • CDNや別サブドメインではファイル処理ルールが甘い

📚 攻撃例

  • アップロード機能自体は問題なく画像のみ受け付けるが、 ファイルが別サーバー(例:cdn.example.com)に保存され、そこでは.phpが実行される

ポイント「場所によって動作が変わる」=攻撃者のチャンス


4. 🧪 表面的な検証のみで実質スルーされるケース

🔍 問題点

  • フロントエンド(JavaScript)での検証のみで、 バックエンドではファイルの検査をしていないパターン。

📚 攻撃者の手法

  • JavaScriptの制限を無視して、Burpで直接リクエストを送信
  • サーバー側にチェックがなければ、実質的に無制限アップロード可能

ポイント検証は必ずサーバー側で行うことが必須


⚠️ 一貫性のないセキュリティが攻撃者の入り口になる

🧠 攻撃者はどこを見ているか?

  • 「拡張子チェックが甘い部分はないか?」
  • 「異なるホストで挙動が変わらないか?」
  • 「検証がフロントエンドだけで終わっていないか?」
  • 「ログイン状態・権限によって検証がスキップされないか?」

セキュリティ対策が”局所的”だと、攻撃者に突かれる。


✅ 安全なファイルアップロードのためにやるべきこと

対策 内容
ホワイトリスト方式の拡張子制限 例:.jpg, .png, .pdf のみ許可する。
マジックバイトによる実ファイルの検査 ファイルヘッダー(先頭バイト)を見て、正しい形式か確認。
サーバー側での一貫した検証処理 フロントエンドやサブドメインに依存しない安全性を確保。
実行可能な場所に保存しない .php を保存しても 実行されない領域 に置く。
ファイル名をランダム化する オリジナルのファイル名を使わず、UUIDなどに変換する。

🎯 まとめ:ファイルアップロード脆弱性が生まれる理由

  • セキュリティ対策が「見かけ倒し」になっている
  • ブラックリスト」「フロントエンドだけのチェック」に頼りがち
  • サイト内やホスト間での検証の不統一により抜け道が生まれる

「安全そうに見える」だけでは防げない! 一貫性・多層防御・サーバーサイドの強化が本当の対策です。

Best regards, (^^ゞ