ヒーロー背景(区切りなし)
指令

サーバー要求の偽造

サーバーサイドのリクエスト偽装に関連する脆弱性は、攻撃者が指定したドメインへアプリケーションがHTTPリクエストを送信するようユーザーに操作された場合に発生します。アプリケーションがプライベート/内部ネットワークにアクセスできる場合、攻撃者はアプリケーションを操作して内部サーバーへリクエストを送信させることも可能です。

いくつかの例を用いてこれを詳しく検討し、実際の動作がどのようなものかをよりよく理解します。

例えば、ユーザーが指定したURLを受け取り、そのURLから画像を生成するAPIを考えてみましょう。これは、ページのプレビューやエクスポートなどに利用できます。

ts
let url = request.params.url ;

let response = http.get(url) ;
let render = response.render() ;

return render.export() ;

URLパラメータはユーザーによって制御されるため、攻撃者は任意のURLに簡単にアクセスできます。場合によっては、URLアクセスに使用するライブラリによっては、「file://」スキーマを使用してローカルファイルにアクセスすることさえ可能です。

AWS上でホストされているSSRF脆弱性を悪用する一般的な手法は、AWSメタデータAPIへのアクセスに利用することです。このAPIにはAWS APIの認証情報が含まれている可能性があります。これにより、アカウント内の他のAWSリソースへの追加アクセスが可能となり、ご想像の通り、これは望ましくない結果を招きます。

緩和策

SSRF脆弱性の緩和策は、場合によっては非常に繊細な作業となり、対象コードの目的によって大きく左右されます。要件に応じて、様々な緩和策を実施することが可能です。

ユーザーが指定したURLは避けてください

特定のケースでは、ユーザーが任意のURLを指定せずに機能を実装できます。それが可能な場合、SSRFのリスクを軽減する最も効果的な方法です。

能力を最小限に抑える

PDFエクスポート機能を実装する場合、インターフェースのないブラウザを使用し、ページのスクリーンショットを撮るだけという方法に傾きがちです。しかし、ブラウザの複雑さや、それらが提供する多数の機能と攻撃対象領域を考慮すると、この方法は必ずしも推奨されません。

適切なツールをタスクに使用することが重要です。場合によっては、単純なHTTPクライアントで十分です。常に機能性を最小化し、攻撃対象領域や利用可能な攻撃ベクトルを減らす方法があります。例えば、HTTPクライアントの場合:

  • 以下のリダイレクトを無効化してください
  • HTTPS以外のすべてのプロトコルを無効にする

いくつかの学校があります

リダイレクトとiframe

プライベートリソース(内部IPアドレスやホスト名)に対するSSRF対策の一般的な手法は、ユーザーが提供するURLを解析し、「拒否リスト」を用いて機密リソースへのアクセスを阻止することである。

なお、この方法はほとんどのケースで効果的ではないことに留意すべきである。クライアントがHTTPリダイレクトやHTML/JavaScriptリダイレクトを辿る場合、あるいはiframeなどの複雑な要素を表示できる場合、この方法は回避される可能性があるためである。

攻撃者は、脆弱なアプリケーションへのURLを提供し、そのアプリケーションが機密リソースへリダイレクトするページをホストしている場合、以下のいずれかの方法で攻撃を実行できます:- HTTP 301/302 メタリダイレクト- HTML メタリダイレクト- 読み込み時にJavaScriptで現在のURLを設定- 内部リソースを表示するiframeを埋め込む これにより、元のURLの検証試行を回避できます。

DNSによる再接続
別の「タイプの」リダイレクトもDNS経由で実行可能です。SSRF攻撃を防止しようとする一般的な手法は、以下の手順で実施されます:

  1. 提供されたURLを分析する
  2. ホスト名を入力し、DNS検索を実行してください
  3. URLが内部/プライベートIPアドレスを指す場合は拒否し、パブリックIPアドレスの場合は許可する

この方法は「DNSリバインディング」に対して脆弱であるため、実際には効果的ではありません。 DNS再バインドは、リモートホストによってTCP接続が閉じられた際の、ほとんどのネットワークスタック(LinuxやWindowsなど)の標準的な動作によって発生します。
リモートホストが接続を強制的に閉じると、IPアドレスを再解決するために別のDNSリクエストを実行した後、再接続を試みます。

これにより、攻撃者は以下の操作を実行できます:

  1. `rebinding.attacker.com` のDNSエントリを作成し、公開IPアドレスと開かれたHTTPポートを設定し、非常に短いTTL(Time-to-Live)を指定してください。
  2. 脆弱なアプリケーションにURL(例:https://rebinding.attacker.com/)を送信します。アプリケーションは解決されたIPアドレスがプライベートでないことを確認し(実際にはプライベートです)、要求された操作を安全であると信じて実行します。
  3. HTTP接続が確立されると、「rebinding.attacker.com」のDNSエントリは内部IPアドレスに置き換えられる
  4. HTTP接続が強制的に閉じられました
  5. これによりアプリケーションは「rebinding.attacker.com」のIPアドレスを再解決し、これが内部IPアドレスを指すようになる
  6. IP解決の保護が既に有効であり、DNSエントリの解決と再接続がすべてカーネル内で実行されるため、アプリケーションはIPアドレスが変更されたことを認識しません。

これにより、プライベートIPアドレスを指すURLの提供に対する保護を効果的に回避できます。

IPv4 対 IPv6

IPv6の利用は、あらゆる「拒否リスト」を回避するもう一つの一般的な手段である。すべてのIPv4アドレスはIPv6アドレスで表現できるため、アクセスしたいIPv4アドレスに対応するIPv6アドレスを使用することで、拒否リストを回避することがしばしば可能である。