説明
ユーザー入力を curl_init、curl_setopt、file_get_contents、fopen などの外部リクエストAPIのURLとして使うと、サーバーサイドリクエストフォージェリ(SSRF)が発生するおそれがあります。
想定される影響
内部ネットワークの探索、クラウドメタデータへのアクセス、内部サービスのアクセス制限の回避につながる可能性があります。
対処方法
URLは固定の許可リストから選び、プライベートIPアドレスの範囲や危険なプロトコルを遮断します。
例
変更前
php
<?php
$url = $_GET['url'];
$body = file_get_contents($url);
変更後
php
<?php
$allowed = ['status' => 'https://status.example.com/health'];
$target = $_GET['target'] ?? '';
if (!isset($allowed[$target])) {
http_response_code(400);
exit;
}
$context = stream_context_create(['http' => ['follow_location' => 0]]);
$body = file_get_contents($allowed[$target], false, $context);
解説:
- 変更前: リクエストAPIに渡すURLをユーザーが制御しています。
- 変更後: 入力はURLとしてではなく、サーバーが管理する許可リストのキーとして使います。未登録の宛先を拒否し、リダイレクトも無効にします。DNSの解決結果とネットワークの送信先も制限して、内部アドレスへ接続できないようにしてください。