OSIIX Library · SSRF Series · Chapter 1

SSRFとは何か

サーバーが「代わりに接続する」ときに起きること

Series
SSRF Series
Chapter
第1章 — SSRFを理解する
Language
日本語
Author
mars70
How to read

この章の読み方

SSRFは、Webセキュリティの用語をある程度知っている人なら短い説明でも理解できます。一方、Webアプリケーションの開発経験が浅い人や、インフラ・運用を中心に担当してきた人にとっては、「URLを受け取ること」と「サーバーが実際に通信すること」がなぜ別の問題になるのか、最初は分かりにくいかもしれません。

本章では、まず仕組みを日常的な言葉で説明し、そのあとでWebアプリケーションやネットワークの言葉へ少しずつ置き換えていきます。すでにSSRFの基本を知っている人は、§4と§6〜§8を中心に読むと、本章の整理の仕方を短時間で確認できます。

Introduction

はじめに

SSRFは Server-Side Request Forgery の略です。日本語では「サーバーサイド・リクエスト・フォージェリ」と表記されることがあります。Forgeryは、直訳すると「偽造」という意味です。

ただ、名前だけを見ると、何を「偽造」しているのか分かりにくいかもしれません。SSRFを理解するときは、まず名前よりも、誰が通信しているのかを見ると分かりやすくなります。

普段、私たちがWebサイトを見るときは、利用者のブラウザがWebサーバーへ接続します。しかしWebサービスには、利用者から受け取った情報をもとに、サーバー側が別の場所へ通信する機能もあります。

たとえば、次のようなものです。

  • URLを指定すると画像を取り込む
  • リンク先の概要を取得してプレビューを表示する
  • 何かのイベントが起きたとき、登録した宛先へ自動で通知する(Webhook)
  • WebページをPDFへ変換する
  • 連携先へサーバー側から接続テストを行う

どれも、現在のWebサービスでは珍しい機能ではありません。これらの機能自体が危険なのではなく、問題はその通信先を誰が、どこまで決められるのかです。

ここでいう通信先は、インターネット上のWebサイトだけではありません。同じサーバー上のサービスや、組織内部のAPIなども、サーバーから見れば通信先になり得ます。

Context

1. サーバーが「代わりに見に行く」

リンク先のプレビュー機能を例にします。SNSやチャットサービスにURLを貼ると、ページのタイトルや説明文、画像が自動で表示されることがあります。

このとき、サービスの実装によっては、利用者のブラウザがリンク先へ直接取りに行くのではなく、WebアプリケーションのサーバーがそのURLへ接続して情報を取得します。

利用者から見ると、「このURLの内容を少し見てきて」とサービスへ頼んでいるようなものです。しかし実際には、利用者が行き先になる情報を渡し、サーバーがその情報を使って接続します。

ここでいう「利用者」には、通常の利用者だけでなく、意図的に想定外の宛先を指定しようとする人も含みます。

利用者
  ↓  URLなどを渡す
Webアプリケーション
  ↓  サーバーが実際に接続する
取得先のリソースやサービス

この構造自体は正常です。画像取り込み、Webhook、文書変換などでも、サーバーが利用者から受け取った情報を使って別の場所へ通信することはあります。

問題になるのは、利用者の影響によって、サーバーの通信先がその機能に許されるべき範囲から外れてしまう場合です。

たとえば設計者は、「利用者が指定するのは公開Webページだけ」と考えていたとします。ところが実際には、サーバーから見える内部サービスまで指定できてしまう。このように、機能として許したい範囲と、実際に通信できる範囲の間にずれがあると、SSRFの問題につながります。

Reachability

2. 利用者とサーバーでは、到達できる範囲が違う

利用者の端末とサーバーでは、見えているネットワークの範囲が違う場合があります。

建物に置き換えて考えてみます。利用者は建物の外にいる人、サーバーは建物の中にいる人です。外にいる人が、中にいる人へ「この部屋を見てきてください」と頼んだとします。

外にいる人自身はその部屋へ直接入れなくても、建物の中にいる人なら行けるかもしれません。中にいる人が建物の中を移動できること自体は、仕事をするうえで普通の能力かもしれません。問題は、外にいる人が、本来なら頼めない場所まで中の人に見に行かせられてしまうことです。

サーバー側の通信にも、これと似た構造があります。利用者から直接は到達できないサービスでも、サーバーからなら接続できる場合があります。

例としては、次のようなものがあります。

  • 同じホストや内部ネットワーク上の管理用サービス
  • 組織内部のAPIやバックエンド
  • クラウド上の仮想マシンが、実行中の自分自身に関する情報を取得するための仕組み(インスタンスメタデータサービス)

実際に通信するのが、入力を受け付けたWebサーバーそのものとは限りません。文書変換やバックグラウンド処理など、別のコンポーネントが通信する場合もあり、その場合はそのコンポーネントから見える範囲が重要になります。

Trust and authority

3. サーバーは、利用者とは違う権限や信頼を持つことがある

到達できる範囲だけでは、SSRFの影響を十分に説明できません。もう一つ重要なのが、サーバーが持つ権限と、接続先から受ける信頼です。

先ほどの建物の例を続けます。建物の中にいる人は、単に中へ入れるだけではなく、社員証を持っていたり、警備員から社員として認識されていたりするかもしれません。

つまり、「どこまで行けるか」と「そこへ行ったとき何を許されるか」は別の話です。

サーバーでも同じように、接続先から見て、利用者とは異なる条件で扱われることがあります。たとえば、送信元のネットワーク位置によって、外部からの要求とは異なる扱いをする内部システムがあります。また、サーバーから送る正規の通信に資格情報が付与される構成もあります。

ただし、SSRFの通信に必ず資格情報が付くわけではありません。また、SSRFによって資格情報に関わる情報へ到達する場合と、サーバーの正規通信に資格情報が付与される場合は別の話です。

SSRFの影響を考えるときは、そのサーバーはどこまで到達できるのかと、到達した先で何を許されるのかを分けて見る必要があります。

Definition

4. これがSSRFの基本構造

ここまでの説明を、一度整理します。

SSRFの基本構造は、次の4段階で考えると分かりやすくなります。

  1. 利用者が、URL、宛先、文書など、サーバーの通信に影響する情報を渡す
  2. サーバー側で、その情報をもとに別の宛先へ通信する
  3. 利用者から影響を受けた情報によって、その利用者やその機能に許されるべき範囲を外れた対象へ通信が向かう
  4. その結果として、情報取得、操作、第三者への通信などの影響が生じる可能性がある

1と2だけでは、SSRFの問題とは言えません。利用者がURLを指定し、サーバーがそのURLを取りに行くこと自体は、正しく設計された通常の機能かもしれません。

1〜3が、SSRFの脆弱性として問題になる部分です。4は、その結果として起こり得る影響です。

本章では、仕組みを理解するために、SSRFを「利用者から影響を受けた情報によって、サーバー側の通信が、その利用者やその機能に許されるべき範囲を外れた対象へ向けられる問題」として捉えます。

ここでいう「許されるべき範囲」は、単に設計者が思い付いていたかどうかではなく、その機能の目的や認可の考え方から見て、利用者に自由に選ばせるべき範囲かどうか、という意味です。

SSRFの成立構造。
サーバー側の通信そのものは通常の機能です。利用者から影響を受けた情報によって、その機能に許されるべき範囲の外へ通信を向けられることがSSRFの問題です。

参考: CSRFとの違い

名前の似た用語にCSRF(Cross-Site Request Forgery)があります。大まかに言えば、CSRFは、ログイン中の利用者(被害者)のブラウザとその認証状態を利用して、意図しない要求を送らせる問題です。一方、SSRFは、サーバー側の通信能力や到達範囲・信頼関係を利用して、意図しない要求を送らせる問題です。

細かな成立条件は異なりますが、「どの主体の通信能力や信頼を使うのか」で区別すると理解しやすくなります。

Impact

5. 何が危険なのか

SSRFの脆弱性が存在するからといって、必ず重大な被害に直結するわけではありません。影響の大きさは、サーバーがどこへ接続できるのか、その接続先が何を提供しているのか、そしてサーバー側からどのような要求を送れるのかによって変わります。

代表的な影響は、次の三つに分けて考えると整理しやすくなります。

非公開情報へ到達する

内部向けの状態情報や管理用データなど、利用者に公開するつもりのなかった情報へ到達する場合があります。

内部サービスの操作につながる

接続先が状態を変更する要求を受け付け、さらにサーバー側からその種類の要求を送れる場合には、読み取りだけでなく何らかの操作につながる可能性があります。

第三者への通信の中継点になる

サーバーが、本来意図していない第三者への通信に使われる場合もあります。この場合、通信は利用者自身の端末からではなく、サービスを運用している側のサーバーから送られるため、接続先からはそのサーバーや組織からの通信として見える可能性があります。

そして、§3で見た権限や信頼は、これらの影響を大きくする要因になり得ます。接続先がサーバーのネットワーク位置や資格情報を信頼していれば、同じ通信でも利用者自身が送った場合より大きな影響につながることがあります。

SSRFを「内部ページを読み取られるだけの問題」と限定しないことが重要です。

Blind SSRF

6. 取得結果が見えなくても問題は起こり得る

「サーバーが何かを取得しても、その内容を利用者へ見せなければ安全なのでは?」と思うかもしれません。

しかし、通信は「内容を読む」ためだけに行われるわけではありません。建物の比喩で言えば、中の人が何も報告を返さなくても、実際に部屋へ行き、扉を開け、何かを届けたのであれば、行為そのものは起きています。

同じように、SSRFでも接続先へ要求が届けば、そこで何らかの処理が実行される場合があります。また、応答内容そのものが表示されなくても、成功したかどうかや応答までの時間などの違いから、利用者から直接は見えない場所にサービスが存在するか、そこへ到達できるかを推測される場合があります。

利用者が自分で用意した接続先を指定できる状況では、その接続先に通信が届いたこと自体を利用者側で確認できる場合もあります。

応答内容が直接見えないタイプを blind SSRF と呼ぶことがあります。第1章で重要なのは用語そのものではなく、「レスポンスを利用者へ返していない」ことは、安全性の証明にはならないという点です。

サーバー側の通信発生と利用者側への結果表示の違い。
通信先からの応答はまずWebアプリ/サーバーへ戻ります。その内容が利用者へ返されるかどうかは別の問題です。
Secondary communication

7. URL入力欄がなくても、サーバー側の通信が発生することがある

SSRFというと、「URLを入力する欄に問題のあるURLを入れる脆弱性」と考えがちです。しかし、利用者がURLを直接入力する画面がなくても、利用者から渡された内容がサーバー側の通信に影響する場合があります。

たとえば、利用者が文書をアップロードし、その文書をサーバー側でPDFへ変換する機能があるとします。文書の中には、画像そのものを埋め込む代わりに、「この場所にある画像を表示する」といった参照だけを持つ形式があります。

サーバー側の変換処理がその参照を読み取り、画像などを追加で取得する場合、利用者は「このURLへ接続してください」と直接指定していなくても、利用者が渡した内容が結果としてサーバーの通信につながります。

本章では、このように利用者からアプリケーションへ送られた最初の要求を処理する途中で、さらに別の取得が発生することを「二次的な通信」と呼びます。

利用者
  ↓
文書やコンテンツ
  ↓
サーバー側の変換・処理
  ↓
参照先を追加取得

SSRFの入口を見るときは、URL入力欄があるかどうかだけではなく、利用者から影響を受ける情報が、どこかでサーバー側の通信につながっていないかを見る必要があります。

Interpretation

8. URLの見た目と、実際の通信は一致するとは限らない

ここまで読むと、「では、利用者が入力したURLを確認して、問題がなければよいのでは?」という疑問が出てきます。

入力を確認することは重要です。ただし、SSRFが難しいのは、最初に見た文字列だけで最後の通信まで説明できるとは限らないことです。

単純化すると、サーバーの通信には次のような流れがあります。

入力されたURLや宛先
        ↓
ソフトウェアが内容を解釈する
        ↓
実際に使う通信先を決める
        ↓
その通信先へ接続する

実際のシステムでは、名前解決、プロキシ、リダイレクト、通信ライブラリなどが関わる場合があります。名前解決とは、ホスト名から実際に接続するためのアドレスを調べる仕組みです。

第1章で押さえたいのは、入力された文字列を確認したことと、実際の通信が意図した範囲に収まっていることは、同じ確認ではないという点です。

第2章では、この「判断した内容」と「実際の通信」の間にどのようなずれが生じ得るのかを整理します。

入力から実際の通信までの処理段階。
最初に確認した入力と、途中の処理を経てサーバーが実際に通信する相手は、同じとは限りません。
Summary

9. 第1章のまとめ

SSRFを理解するときは、「危険なURLを見つける問題」とだけ考えないことが大切です。

まず、次の三点を押さえてください。

  1. サーバー側から通信する機能では、利用者が行き先に影響を与えても、実際に通信するのはサーバー側である
  2. サーバーは利用者とは違う到達範囲や権限・信頼を持つことがある
  3. 利用者の影響によって、サーバーの通信がその機能に許されるべき範囲の外へ向かうと、SSRFの問題になる

さらに、応答が画面へ表示されなくても問題は起こり得ること、URL入力欄がなくても二次的な通信が発生する場合があること、入力されたURLから想定した宛先と実際の通信先が常に一致するとは限らないことも重要です。

Next chapter

10. 次章へ

では、行き先をきちんと確認すればSSRFは防げるのでしょうか。方向としては正しいのですが、「確認した」というだけでは十分ではありません。

どの段階で確認したのか。その判断は、実際に通信する瞬間まで有効なのか。通信は本当に想定した経路を通るのか。

こうした場所で、最初の判断と実際の通信がずれることがあります。

第2章では、「なぜSSRF対策は難しいのか」を、この判断と実通信のずれという観点から整理します。