SSRF(Server-Side Request Forgery)は、サーバーに外部リクエストを送らせることで、内部システムへアクセスできてしまう脆弱性です。
多くのアプリケーションでは、SSRFを防ぐために「localhost」や「/admin」といった危険な文字列をブロックする対策(ブラックリスト)が実装されています。
しかし、こうした対策は必ずしも安全とは限りません。
本記事では、PortSwigger Web Security Academyのラボ「SSRF with blacklist-based input filter」をもとに、ブラックリスト型SSRF対策がどのように回避されるのかを解説します。
さらに、WordPressに置き換えた場合のリスクについても考えていきます。
「SSRF with blacklist-based input filter」ラボ概要
今回のラボには、在庫確認機能(stock check)が実装されています。
この機能は、指定されたURLにサーバーがアクセスし、在庫情報を取得する仕組みです。
つまり、ユーザーが入力したURLによっては、サーバーが任意の場所へリクエストを送ってしまう可能性があります。
攻撃の目的
今回のゴールは以下の通りです。
- localhost上の管理画面(/admin)にアクセスする
- 管理画面からユーザー「carlos」を削除する
脆弱性のあるポイント
問題となるのは、このパラメータです。
stockApi=http://stock.weliketoshop.net:8080/...このURLはサーバー側で実行されるため、書き換えることでSSRFが成立します。
なぜ単純な攻撃が通らないのか
例えば以下のように書き換えても失敗します。
http://localhost/adminこれは、アプリケーション側で以下のような対策が行われているためです。
- 「localhost」のブロック
- 「/admin」のブロック
- 許可ドメイン(stock.weliketoshop.net)のチェック
回避テクニック① IPアドレス表現の変換
「localhost」の代わりに、別の表現を使います。
127.1これは127.0.0.1と同じ意味を持ちます。
フィルターは「localhost」しか見ていないため、回避可能です。
回避テクニック② 二重URLエンコード
「/admin」もブロックされているため、エンコードして隠します。
%2561%2564%256d%2569%256eこれは二重エンコードされており、最終的に「admin」に戻ります。
- フィルター → adminと認識しない
- 実際のアクセス → adminとして解釈される
回避テクニック③ ホスト偽装(@トリック)
今回のラボの核心部分です。
http://stock.weliketoshop.net@127.1/%2561%2564%256d%2569%256eこのURLは次のように解釈されます。
- stock.weliketoshop.net → ユーザー情報
- 127.1 → 実際の接続先
フィルターは許可ドメインが含まれていると判断、実際は localhost にアクセスされます。
最終的な攻撃リクエスト
stockApi=http://stock.weliketoshop.net@127.1/%2561%2564%256d%2569%256e/delete?username=carlosこのリクエストにより、管理画面の機能を利用してユーザー削除が実行されます。
WordPressでSSRFが発生するケースと注意点
WordPressでも、外部URLを取得する機能は多く存在します。
例えば以下のようなケースです。
- プラグインによる外部API取得
- RSSフィードの読み込み
- 画像URLの取得
- Webhook処理
これらの機能で、ユーザー入力をそのままURLとして使用している場合、SSRFのリスクが発生します。
ブラックリストでの防御が危険な理由
今回のラボから分かることは明確です。
- 文字列ベースのチェックは簡単に回避される
- URLの見た目と実際の接続先は一致しない
- フィルターと実処理にズレがある
SSRF対策の正しい方法
本来必要な対策は以下の通りです。
- URLを正しくパースする
- DNS解決後のIPをチェックする
- 内部IPへのアクセスを禁止する
- ホワイトリスト方式を採用する
WordPressセキュリティ診断時のチェックポイント
SSRFは見つけにくい脆弱性ですが、いくつかのポイントを押さえることで発見しやすくなります。
チェックポイント
- 外部URLをサーバーが取得する機能があるか
- ユーザー入力がそのままURLとして使われていないか
- localhostや内部IPにアクセスできないか
- 特定の文字列だけブロックされていないか(ブラックリスト)
回避テスト
ブラックリストがある場合は、以下を試します。
- IP表現の変更(127.1 / 2130706433 など)
- URLエンコード・二重エンコード
- ホスト偽装(@トリック)
詳しく知りたい方へ
SSRF診断の具体的な手順や検証パターンは、別記事で詳しく解説しています。
まとめ|SSRFは文字列チェックでは防げない
ブラックリスト型のSSRF対策は、一見すると安全に見えますが、実際にはさまざまな方法で回避されてしまいます。
今回のラボでは、以下の3つのテクニックを組み合わせることで防御を突破しました。
- IP表現の変換
- 二重URLエンコード
- ホスト偽装(@トリック)
重要なのは、文字列ではなく、最終的な接続先を検証することです。
