Hello there, ('ω')ノ
✅ ファイルアップロード防御の基本
1️⃣ 第一の防御線:危険ファイルのアップロード自体を防ぐ
2️⃣ 第二の防御線:万が一アップロードされても サーバー上で実行できないようにする
🎯 第二の防御線がなぜ重要か?
どんなに厳重に検証していても、
- 開発者のうっかり
- 新しいバイパス手法
- ライブラリのバグ などで 「危険なファイルのすり抜け」 は完全には防げません。
そこで 「実行不可の保存場所」 が最終防衛ラインになります。
✅ サーバーの実行動作の仕組み
通常、サーバーは
- MIMEタイプやファイル拡張子
- ディレクトリ設定(Apacheの
Options -ExecCGI
や nginxのlocation
設定など) を元に「このファイルはスクリプトとして実行すべきかどうか」を判断します。
🎭 危険なケースの例
もし攻撃者がWebシェルをアップロードして
ユーザーが直接アクセスできる場所(例:/static/
, /uploads/
)に保存された場合:
📚 攻撃リクエスト
GET /static/exploit.php?command=id HTTP/1.1 Host: normal-website.com
🎯 想定されるレスポンス(悪いパターン)
HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 39 <?php echo system($_GET['command']); ?>
- サーバーがPHPを実行せず中身をそのまま返した → ソースコード漏洩(情報漏洩)
もしくは
- 実行してしまった → リモートコード実行(RCE)
✅ 正しい防御策
防御策 | 説明 |
---|---|
✅ 実行可能ファイルは限定されたディレクトリにのみ配置 | 通常は /var/www/html 配下の一部 |
✅ アップロードディレクトリは完全に実行不可に設定 | 例:Apacheなら .htaccess: php_flag engine off |
✅ nginxではdisable_php カスタムディレクティブやdeny all 設定 |
|
✅ ファイルアップロード先を外部ストレージ(例:S3バケットなど) にする | 実行機能なし |
🛡️ 理想的な設計イメージ
/var/www/html/ → 実行可能エリア (管理者のみ書き込み可) /var/www/uploads/ → 実行不可エリア (ユーザーアップロード専用)
- 仮に
shell.php
が/var/www/uploads/
に置かれても - PHPエンジンがOFFなので実行できない → 単なるファイルデータとして扱われる
✅ 結論:実行防止が「最後の砦」
- 「アップロード→Webから直接アクセスできる」 この設計は便利ですが超危険
- サーバーの設定レベルで絶対にスクリプト実行不可 にしておくのが鉄則
- これができていれば 万が一Webシェルがすり抜けても被害ゼロ
「万全の一次検証 + 完璧な二次防御」 この2段階を徹底することが、 世界標準のWebアプリ脆弱性診断(ペネトレーションテスト)の基本中の基本です。
Best regards, (^^ゞ