サーバーサイドリクエストフォージェリ

サーバーサイドリクエストフォージェリ

説明

ユーザー入力を 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の解決結果とネットワークの送信先も制限して、内部アドレスへ接続できないようにしてください。

参考資料