title: 【転載】サーバーサイドリクエストフォージェリ(SSRF)とは?
date: 2021-08-14 09:01:57
comment: false
toc: true
category:
- シェア
tags: - サーバーサイド
- フォージェリ
- SSRF
- リクエスト
この記事は、サーバーサイドリクエストフォージェリ(SSRF)とは?から転載されています。
- 原文アドレス:What is Server-Side Request Forgery (SSRF)?
- 原文著者:Ian Muscat
- 訳文出自:掘金翻訳計画
- 本文永久リンク:github.com/xitu/gold-m…
- 訳者:MoonBall
- 校正者:PassionPenguin、kamly
サーバーサイドリクエストフォージェリ(SSRF)脆弱性は、攻撃者が脆弱なアプリケーションのバックエンドサービスから悪意のあるリクエストを送信することを可能にします。攻撃者は通常、ファイアウォールの背後にある内部システムに対して SSRF 攻撃を行います。これらの内部システムは外部ネットワークからアクセスできません。攻撃者はまた、サーバーのループバックインターフェース(127.0.0.1)を介してアクセス可能なサービスに SSRF を利用してアクセスすることもできます。
攻撃者がアプリケーションが送信するリクエストを完全に制御または部分的に制御できる場合、SSRF 脆弱性が発生します。一般的な例は、攻撃者が第三者サービスの URL を制御でき、アプリケーションがその URL に対してリクエストを発行することです。
以下は、SSRF 攻撃に対して脆弱な PHP の例です。
<?php
/**
* GET変数 'url' が設定されているか確認します
* 例 - http://localhost/?url=http://testphp.vulnweb.com/images/logo.gif
*/
if (isset($_GET['url'])){
$url = $_GET['url'];
/**
* SSRF攻撃に対して脆弱なリクエストを発行します
* リクエストを発行する前に
* $urlを検証していません
*/
$image = fopen($url, 'rb');
/**
* 正しいレスポンスヘッダーを送信します
*/
header("Content-Type: image/png");
/**
* 画像の内容をレスポンスします
*/
fpassthru($image);}
上記の例では、攻撃者はurlパラメータを完全に制御できます。攻撃者はインターネット上の任意のウェブサイトや攻撃対象のサーバー(localhost)上のリソースに GET リクエストを発行できます。
以下の例では、攻撃者は Apache HTTP サービスにリクエストを発行します。この Apache HTTP サービスはmode_statusモードが有効になっています(このモードはデフォルトで有効です)。
GET /?url=http://localhost/server-status HTTP/1.1
Host: example.com
攻撃者はまた、SSRF を使用して Web サーバーがアクセス権を持つ他の内部リソースにリクエストを発行することもできますが、それらは公開されていません。たとえば、攻撃者は AWS/Amazon EC2やOpenStackのクラウドサービスインスタンスのメタデータにアクセスできます。攻撃者は SSRF を利用して創造的な手法を用いることもでき、内部 IP のポートスキャンを行うことができます。
GET /?url=http://169.254.169.254/latest/meta-data/ HTTP/1.1
Host: example.com
**http://およびhttps://** の URL プロトコル以外にも、攻撃者はあまり知られていない古い URL プロトコルを利用してローカルシステムや内部ネットワーク上のファイルにアクセスできます。
以下の例では、**file:///** プロトコルを使用しています。
GET /?url=file:///etc/passwd HTTP/1.1
Host: example.com
一部のアプリケーションは、攻撃者がより奇妙な URL プロトコルを使用することを許可する場合があります。たとえば、アプリケーションが cURL を使用してリクエストを発行する場合、攻撃者はdict:// URL プロトコルを使用して任意のホストとポートにリクエストを発行し、カスタムデータを送信できます。
GET /?url=dict://localhost:11211/stat HTTP/1.1
Host: example.com
上記のリクエストは、アプリケーションがlocalhostの 11211 ポートに接続し、stat
文字列を送信します。ポート 11211 はMemcachedのデフォルトポートであり、通常は外部に公開されません。
サーバーサイドリクエストフォージェリの検出#
サーバーサイドリクエストフォージェリを自動的に検出するには、中間サービスを使用する必要があります。なぜなら、この種の脆弱性を検査するには、外部からアクセス可能で遅延が存在する方法が必要だからです。Acunetix は、AcuMonitorを中間サービスとして使用することでこの問題を解決しています。
スキャン中、Acunetix は異なる AcuMonitor URL にリクエストを発行します。もし AcuMonitor がこれらの異なる URL のいずれかでリクエストを受け取った場合、Acunetix に通知します。その後、Acunetix は SSRF アラートを発出します。
下の図は、AcuMonitor を使用した Acunetix のスキャン結果で、サーバーサイドリクエストフォージェリを検査しています。このアラートには HTTP リクエストの情報が含まれています。発信元のサーバーの IP アドレスやリクエストに含まれるUser-Agent
文字列(存在する場合)などの情報が含まれています。これらの情報は、開発者が問題の原因を特定し、修正するのに役立ちます。
サーバーサイドリクエストフォージェリの排除#
ユーザー入力に単純なブラックリストや正規表現を適用することは、SSRF 攻撃を排除するための悪い方法です。通常、ブラックリストはほとんど効果のないセキュリティ制御手段です。攻撃者は常にそれを回避する方法を見つけることができます。この例では、攻撃者は HTTP リダイレクト、ワイルドカード DNS サービス(例えばxip.io)または代替 IP エンコーディングを使用してブラックリストを回避することができます。
ホワイトリストと DNS 解決#
サーバーサイドリクエストフォージェリを回避する最も堅牢な方法は、アプリケーションがアクセスする必要のある DNS 名と IP アドレスをホワイトリストに追加することです。ホワイトリストメカニズムがニーズを満たさない場合、ブラックリストメカニズムに依存する必要がある場合は、ユーザー入力を適切に検証することが非常に重要です。たとえば、プライベート IP アドレスへのリクエストを許可しないこと(プライベート IP アドレスはRFC 1918を参照)です。
ただし、ブラックリストを使用するシナリオでは、SSRF を正しく排除する方法はアプリケーションによって異なります。言い換えれば、ブラックリストメカニズムを使用して SSRF 脆弱性を修正するための銀の弾は存在しません。なぜなら、それはアプリケーションの機能とビジネスニーズに高度に依存するからです。
レスポンスの処理#
攻撃者にレスポンスデータが漏洩しないように、受信したレスポンスが期待される内容であることを確認する必要があります。いかなる場合でも、サーバーが送信したリクエストの元のレスポンスボディをクライアントに渡すべきではありません。
使用しない URL プロトコルの無効化#
アプリケーションが HTTP または HTTPS のみを使用してリクエストを発行する場合、これらの URL プロトコルのみを許可します。使用しない URL プロトコルを無効にすると、攻撃者はfile:///、dict://、ftp://、および **gopher://** のような潜在的に危険なプロトコルを使用してリクエストを発行できなくなります。
内部サービスの認証#
デフォルトでは、Memcached、Redis、Elasticsearch、MongoDB のようなサービスは認証を要求しません。攻撃者はサーバーサイドリクエストフォージェリ脆弱性を利用して、認証なしでこれらのサービスにアクセスできます。したがって、アプリケーションのセキュリティを確保するために、可能な限り認証を有効にすることが最善です。たとえそれがローカルネットワーク上のサービスであってもです。
訳文に誤りや改善点がある場合は、掘金翻訳計画で訳文を修正し PR することができ、相応の報酬ポイントを得ることができます。記事の冒頭にある本文永久リンクは、この記事の GitHub 上の Markdown リンクです。
掘金翻訳計画は、質の高いインターネット技術記事を翻訳するコミュニティで、出典は掘金の英語シェア記事です。内容はAndroid、iOS、フロントエンド、バックエンド、ブロックチェーン、製品、デザイン、人工知能などの分野をカバーしています。質の高い訳文をもっと見たい方は、掘金翻訳計画、公式微博、知乎専欄を引き続きご覧ください。