【入門編】 Server-Side Request Forgery (SSRF) によるクラウドメタデータへのアクセス – オフェンシブセキュリティ & リバースエンジニアリング防御ガイド

こんにちは!普段はシステムを作る側の開発者として頑張っているけれど、「セキュリティ」という言葉を聞くとなんだか少し身構えてしまう……そんな新人IT担当者やエンジニアの皆さん、いらっしゃいませんか?

ネットワークやサーバーの仕組みを覚えるだけでも大変なのに、次から次へと新しいサイバー攻撃のニュースを聞くと、不安になってしまいますよね。でも、大丈夫です!セキュリティの対策も、基本の考え方は私たちの日常生活にある「防犯」とまったく同じなんです。

今回は、最近のクラウド環境でとても狙われやすい「SSRF(サーバーサイド・リクエスト・フォージェリ)」という攻撃と、それがクラウドの「メタデータ」という秘密の宝箱をどうやって奪おうとするのか、そしてどうやってそれを防げばいいのかを、身近な例えを交えながら一歩ずつ優しく紐解いていきたいと思います。

—

1. 家の鍵に例えて理解する「SSRF」の仕組み

まずは、SSRFがどんな攻撃なのかをイメージしてみましょう。

皆さんが住んでいるマンションを想像してください。そのマンションには、住人だけが使える「管理人室」があり、そこには住民全員のプライベートな情報(合鍵や連絡先など)が保管されているとします。

  • 通常の侵入者(外部からの攻撃):

管理人室のドアを直接こじ開けようとしますが、頑丈な鍵がかかっているので入れません。

  • SSRF(今回の攻撃):

攻撃者は、直接管理人室に入ろうとはしません。その代わり、「とてもお人好しで、頼まれたら何でも代わりにやってくれる管理人さん(Webサーバー)」を見つけます。

攻撃者はこの管理人さんに対して、「あそこのお店からお弁当を買ってきて!」とお願いするフリをして、こっそり「管理人室の裏口に行って、中の書類を取ってきて!」と耳打ちします。
お人好しの管理人さんは、疑うこともなく管理人室の裏口に行き、書類を取ってきて攻撃者に渡してしまいました……。

これがSSRFの正体です。「外から直接見えない内部のサーバーに、裏側のプログラム(サーバー)を身代わりにしてアクセスさせる攻撃」なんですね。

—

2. クラウドの「メタデータ」ってなに?

さて、現代のシステムはAWS(Amazon Web Services)やGCP(Google Cloud Platform)、Microsoft Azureといった「クラウド」の上で動くことがほとんどです。

これらのクラウドには、動いているプログラム自身が「今、自分はどんな設定で動いているんだっけ?」を確認するための、いわば「システム手帳」のような特別な場所があります。これをメタデータサービス(IMDS: Instance Metadata Service)と呼びます。

このメタデータには、サーバーのIPアドレスやOSの種類だけでなく、「このサーバーを操作していい特別なパスワード(一時的なアクセスキー)」まで書かれていることがあります。

もし、先ほどの「お人好しな管理人さん(脆弱性のあるWebサーバー)」がこのメタデータの場所を知られてしまうと、どうなるでしょうか?
攻撃者はSSRFを使って、管理人さんに「ちょっとそのシステム手帳の中身を見せてきて!」と頼み、クラウドのマスターキーをごっそり盗み出してしまうのです。これが、クラウドにおけるSSRFの恐ろしいシナリオです。

—

3. 被害を防ぐための「防犯の仕組み」:IMDSv2と防御ヘッダー

「じゃあ、お人好しな管理人さんが勝手にお使いに行かないようにするにはどうすればいいの?」と思いますよね。
クラウドの世界では、この裏口アクセスを防ぐために、とても賢い防犯システムが用意されています。それが「IMDSv2」という仕組みと、特別な「防御ヘッダー(トークン)」です。

古い仕組み(IMDSv1)では、宛先を知っていれば誰でも一言でメタデータを見ることができました。しかし、新しい仕組み(IMDSv2)では、こんなルールが追加されました。

1. 合言葉(トークン)が必要:
メタデータを覗きに行く前に、まず「この特別な合言葉を発行してください」という専用のリクエストを投げないと、中身を見せてくれません。
2. SSRFでは合言葉が取れない:
通常のSSRF攻撃は「これを取ってきて」と一方向にお願いするだけのことが多いため、事前に「合言葉を発行してもらう」というステップをうまく踏めません。つまり、泥棒は合言葉が分からないので、宝箱が開けられないというわけです。

—

4. 実務で使える!具体的な対策とコード例

それでは、実際に私たちが開発やインフラの現場でどのようにこの対策を施すべきか、コードや設定の例を見ていきましょう。

対策その1:アプリケーション側で「外部からのURL」を厳しくチェックする

プログラムがユーザーから受け取ったURL(例: https://example.com/api?url=...)をそのまま cURL や requests で読み込んでいる場合、そこがSSRFの入り口になります。
信頼できないURLを受け取らないように、許可されたドメイン以外は弾く(ホワイトリスト方式)ようにしましょう。

以下は、PHPで外部URLをリクエストする際に、安全性を高めるためのサンプルコードです。

<?php
/**
 * 安全に外部URLへリクエストを送るためのサンプル関数
 * SSRFを防ぐため、許可されたドメイン以外へのアクセスをブロックします
 */
function safeCurlRequest($targetUrl) {
    // 1. URLの構文が正しいかチェック
    $parsedUrl = parse_url($targetUrl);
    if ($parsedUrl === false || !isset($parsedUrl['host'])) {
        return "エラー: 無効なURLです。";
    }

    $allowedHost = 'api.trusted-partner.com';

    // 2. 許可されたドメイン(ホワイトリスト)と一致するか確認
    if ($parsedUrl['host'] !== $allowedHost) {
        // 許可されていないドメインの場合は処理を中断
        return "エラー: このドメインへのアクセスは許可されていません。";
    }

    // 3. 安全性が確認できた場合のみ、リクエストを実行
    $ch = curl_init($targetUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    // 内部IP(127.0.0.1や169.254.169.254など)へのリクエストを防ぐ追加設定も有効です
    
    $response = curl_exec($ch);
    curl_close($ch);

    return $response;
}
?>

対策その2:AWSでの「IMDSv2」の強制(インフラ側の設定)

AWSを使っている場合、クラウドの設定で古いメタデータ(IMDSv1)を禁止し、常にIMDSv2を強制するように設定します。
Terraformなどのインフラ管理ツールを使う場合は、次のように設定ファイルに記述します。

# AWS EC2インスタンスの設定例
resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"

  # メタデータサービスのセキュリティ設定
  metadata_options {
    http_endpoint = "enabled"
    # IMDSv2を必須(required)に設定することで、SSRF経由の不正アクセスを防ぎます
    http_tokens   = "required" 
  }

  tags = {
    Name = "SecureWebServer"
  }
}

この http_tokens = "required" という一行が、先ほどお話しした「合言葉(トークン)を必須にする」という強力な防犯ロックになります。

—

まとめ:一歩ずつ、安全なシステムを作っていこう

いかがでしたでしょうか?
SSRFやクラウドのメタデータという言葉を聞くと難しく感じられたかもしれませんが、要するに「サーバーが意図せず内部の機密情報を外部に漏らしてしまうのを、アプリの入力チェックとクラウドの合言葉(IMDSv2)でがっちりガードする」ということです。

セキュリティ対策は、一度にすべてを完璧にする必要はありません。「今回はURLのホワイトリストを入れよう」「次はクラウドの設定を確認しよう」と、一歩ずつ確実にできることを増やしていくことが何よりも大切です。

日々の開発やインフラ構築の中で、ぜひ今回の内容を思い出して役立ててくださいね。皆さんの安全で素晴らしいシステム作りを、これからも応援しています!

コメント

タイトルとURLをコピーしました