SSRF(サーバサイドリクエストフォージェリ)とは?起きるパターンと対策法

SSRF(サーバサイドリクエストフォージェリ)とは?起きるパターンと対策法

#セキュリティ#Web開発#脆弱性対策

SSRF(サーバサイドリクエストフォージェリ)は、サーバに攻撃者の指定した宛先へリクエストを送らせ、内部ネットワークやクラウドの機密に到達される脆弱性です。 クラウド利用の拡大で重要度が上がっており、対策の勘所は宛先を許可リストで縛れているかどうかです。

SSRFとは

SSRF(Server-Side Request Forgery、サーバサイドリクエストフォージェリ):サーバが外部リソースへアクセスする機能を悪用し、攻撃者が指定した宛先へサーバ自身にリクエストを送らせる脆弱性です。 リクエスト先のURLをユーザー入力で決める設計が根本原因になります。

サーバは外部からは到達できない内部ネットワークやクラウドのメタデータサービスに手が届きます。 攻撃者はサーバを踏み台に、内部システムへの到達、クラウドのメタデータエンドポイント(169.254.169.254)からの認証情報の窃取に至ります。 クラウド環境では一時認証情報の奪取に直結するため、近年とくに重要度が上がっています。

SSRFが起きるパターン

典型的な弱点は次のとおりです。

  • URLを指定して外部の画像やページを取得する機能で、宛先を検証していない
  • Webhookやプレビュー生成、PDF化など、ユーザーが渡したURLへサーバがアクセスする機能
  • 宛先のホスト名を許可リストで縛らず、内部IPやlocalhostへのアクセスを許している
  • リダイレクトを追跡する実装で、外部URLから内部宛先へ転送されて回避される
  • DNSの解決結果を検証と実アクセスで別々に引き、その隙を突かれる
  • ドメインは許可リストにあるが、そのドメインが内部IPを指すよう仕込まれている(DNSリバインディング)

共通するのは「サーバがアクセスする宛先を外部入力で決められ、内部やメタデータへ到達できてしまう」という点です。

対策法

原則は「サーバがアクセスできる宛先を許可リストで限定し、内部への到達を塞ぐ」ことです。

  • アクセスを許す宛先ホストを明示的なホワイトリストで管理する。これが本命の対策になる
  • 内部IPアドレス帯やlocalhost、メタデータエンドポイントへのアクセスを遮断する
  • クラウドのメタデータをトークン必須の方式(IMDSv2など)に切り替え、単純な取得を防ぐ
  • リダイレクトを無効化するか、転送先も同じ許可リストで再検証する
  • 外部アクセス用の経路をネットワークレベルで内部から分離する(被害軽減策)

内部IPの単純な除外だけでは回避されやすく、本命は許可リストによる宛先の限定です。 ユーザー入力でURLを受け取る機能を洗い出し、宛先の許可リストとメタデータ保護を先に固めるのが費用対効果の高い進め方になります。

Rails での事例

危険なのは、ユーザーが渡したURLへサーバがそのままアクセスする形です(画像の取り込み、Webhook、URLプレビューなど)。

# 危険:内部IPやクラウドのメタデータエンドポイントにも到達できる
require "open-uri"

def import
  content = URI.open(params[:url]).read
end

params[:url]http://169.254.169.254/...(クラウドのメタデータ)や http://localhost:6379(内部の Redis)を渡されると、外部からは触れないはずの資源にサーバ経由で到達されます。

対策は許可リストによる宛先の限定です。 スキームとホストを検証し、解決先が内部IPでないことまで確認します。

require "resolv"
require "ipaddr"

ALLOWED_HOSTS = %w[images.example.com cdn.example.com].freeze
PRIVATE_RANGES = [
  IPAddr.new("10.0.0.0/8"), IPAddr.new("172.16.0.0/12"),
  IPAddr.new("192.168.0.0/16"), IPAddr.new("127.0.0.0/8"),
  IPAddr.new("169.254.0.0/16")
].freeze

def safe_fetch(raw)
  uri = URI.parse(raw)
  raise "scheme" unless %w[http https].include?(uri.scheme)
  raise "host"   unless ALLOWED_HOSTS.include?(uri.host)

  address = IPAddr.new(Resolv.getaddress(uri.host))
  raise "private" if PRIVATE_RANGES.any? { |r| r.include?(address) }

  # リダイレクトは追わない(追う場合は転送先も同じ検証にかける)
  Net::HTTP.get(uri)
end

なお、許可ホストの検証と実アクセスで名前解決が2回走ると、その間に応答を差し替える DNS リバインディングの余地が残ります。 厳密に守るなら、検証で得たIPアドレスに対して直接接続します。 外部取得用の経路をネットワーク側で内部から分離できるなら、それが最も確実な被害軽減策です。 IMDSv2(トークン必須のメタデータ方式)への切り替えも、クラウド環境では併せて行います。

まとめ

SSRF対策の要点を整理します。

  • 根本原因は「サーバがアクセスする宛先を外部入力で決められること」。URLを受け取る機能(画像取り込み・Webhook・プレビュー生成・PDF化)の洗い出しが出発点になる
  • 本命の対策は宛先ホストの許可リスト。内部IPアドレス帯・localhost・メタデータエンドポイントの遮断を重ねる
  • クラウドではIMDSv2などトークン必須のメタデータ方式に切り替える。SSRFが成立しても認証情報の単純な窃取を防げる
  • リダイレクトの追跡とDNSリバインディングが検証回避の抜け道。転送先の再検証と、検証済みIPへの直接接続で塞ぐ
  • 外部取得用の経路をネットワークレベルで内部から分離できれば、被害軽減策として最も確実

「URLを受け取ってサーバが取りに行く」機能は、画像プレビューやWebhookなど気づかないうちに増えていきます。既存コードの点検は、この形の機能の棚卸しから始めるのが近道です。

関連して読める記事

CSRFはSSRFと名前が似ていますが、騙す相手が違います。CSRFが利用者のブラウザに意図しないリクエストを送らせるのに対し、SSRFはサーバ自身を踏み台にします。混同しやすいのでセットで整理しておくと理解が定着します。また、「外部入力がそのまま解釈されて想定外の動作に至る」という構図はSQLインジェクションと共通し、「サーバ側で確認せずに要求へ応えてしまう」という点はIDORとも通じます。

CSRF(クロスサイトリクエストフォージェリ)とは?起きるパターンと対策法

CSRF(クロスサイトリクエストフォージェリ)の仕組みと起きるパターン、CSRFトークンとSameSite Cookieを軸にした対策を整理します。Railsで検証を外してしまう skip_before_action の罠と、React(TypeScript)からのトークン送信ヘッダの組み込み方を、危険なコードと安全な書き方の具体例で示します。

2026年7月23日

SQLインジェクションとは?起きるパターンと対策法

SQLインジェクションの仕組みと起きるパターン、そしてプレースホルダ(パラメータ化クエリ)を軸にした対策を整理します。Rails(Active Record)で穴が開く where の文字列展開と order のカラム名、その安全な書き方を具体的なコード例で示します。

2026年7月22日

IDOR(安全でない直接オブジェクト参照)とは?起きるパターンと対策法

IDOR(安全でない直接オブジェクト参照)の仕組みと起きるパターン、所有者チェックを軸にした対策を整理します。RailsのOrder.find(params[:id])がそのまま穴になる理由と、current_user起点の取得への直し方を具体的なコード例で示します。OWASP API Security Top 10で1位のBOLAに相当する脆弱性です。

2026年7月23日
この記事をシェア