Shikata Ga Nai

Private? There is no such things.

ユーザーアップロードディレクトリでのファイル実行防止:Webシェル設置を阻止する最も重要な対策

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, (^^ゞ