PHP セキュリティ解説 · 防御向け
PHP の SSRF とは?直し方
URL プレビュー、Webhook、画像の取り込み、PDF 生成などの機能はサーバーに URL を取得させます。その URL を訪問者が操作できれば、自分では届かない場所へサーバーを向けられます。
最終更新
どんな問題か
サーバーはたいてい信頼されたネットワークの内側にあります。そこからのリクエストはデータベース、管理画面、ほかのマイクロサービス、認証情報を返すクラウドのインスタンスメタデータに届きます。SSRF は URL を取得する機能を内部ネットワークへのプロキシに変えてしまいます。MITRE では CWE-918 に分類され、OWASP には専用の対策チートシートがあります。
見つけ方
- 入力から URL を受け取る
curl_setopt(... CURLOPT_URL ...)、file_get_contents($var)、fopen($var)、get_headers()、Guzzle などの HTTP クライアント呼び出しを検索します。 - リモートの内容を取得する機能をすべて洗い出します:Webhook、アバターや画像の取り込み、リンクプレビュー、フィードリーダー、PDF やスクリーンショットの生成、外部エンティティを含む XML 解析。
- Web サーバーの外向き通信を確認します。
169.254.169.254、localhost、プライベート帯域への想定外のリクエストは危険信号です。
直し方
- 機能が本当に必要とするホストとスキーム(通常は
httpsのみ)だけを許可し、ほかは拒否します。 - ホスト名を自分で解決してプライベート、ループバック、リンクローカルのアドレスを拒否し、解決した IP に接続して、確認と使用の間に DNS が変わらないようにします。
- リダイレクト追従を無効にし(
CURLOPT_FOLLOWLOCATIONを false)、CURLOPT_PROTOCOLSでプロトコルを制限します。 - クラウドではインスタンスメタデータにセッショントークンを必須にし(例:AWS IMDSv2)、ファイアウォールで外向き通信を制限します。
読み取り専用の確認と安全な書き方
# Find server-side fetches that may take a user-supplied URL (read-only)
grep -rnE "(curl_setopt.*CURLOPT_URL|file_get_contents\s*\(\s*\$|fopen\s*\(\s*\$)" --include=*.php . | grep -v /vendor/
// Allowlist hosts and schemes before fetching
$u = parse_url($url);
$allowed = ['api.example.com'];
if (($u['scheme'] ?? '') !== 'https' || !in_array($u['host'] ?? '', $allowed, true)) {
throw new RuntimeException('URL not allowed');
}
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);127.0.0.1 をブロックすれば十分ですか?
いいえ。別表記の IP、IPv6、プライベートアドレスに解決されるドメイン、リダイレクトで単純なブロックリストは回避されます。OWASP は許可リストを勧めています。
WAF で SSRF は防げますか?
一部のパターンは止められますが、どの内部ホストが重要かは WAF にはわかりません。コードで直してください。
ほかの PHP の脆弱性の種類
- PHP オブジェクトインジェクションとは?直し方PHP オブジェクトインジェクションは、利用者が操作できる入力が unserialize() に届くと起き、マジックメソッドを通じて攻撃者が選んだ処理を実行させるオブジェクトが生成され得ます。
- PHP ファイルインクルード(LFI/RFI)とは?直し方ファイルインクルードは利用者の入力が include や require のパスを左右すると起き、攻撃者はローカルファイルを読み(LFI)、allow_url_include が有効ならリモートのコードを実行できます(RFI)。
- PHP の XSS とは?防ぎ方クロスサイトスクリプティング(XSS)は PHP のページが利用者の操作できるデータをエスケープせずに HTML に出すと起き、攻撃者のスクリプトがほかの訪問者のブラウザで実行されます。
- phpinfo() の露出:なぜ問題か、どう直すか公開された phpinfo() ページは正確な PHP のバージョン、読み込まれたモジュール、ファイルパス、しばしば環境変数や秘密情報まで明かし、PHP2Shell のような脆弱性を狙う手がかりになります。
出典
外部リンクは本サイトの外に移動します。本サイトはエクスプロイトコードを掲載しません。
- CWE-918: Server-Side Request Forgery (SSRF) — MITRE CWE
- Server-Side Request Forgery Prevention Cheat Sheet — OWASP Cheat Sheet Series