サイバー脆弱性による被害から資源を広く守るため、各組織は知識を深め、既存の脆弱性について把握する必要があります。本記事では、CSRFについて詳しく解説しています。
XSSの類似として、XSSと並び、正当なユーザに許可されていない操作を強制的に行わせる脆弱性の一つです。ウェブサイトでは、2要素認証やパスワードなどでエンドユーザの認証を行い、サービスやアプリへのアクセスを許可します。これにより、利用者とサイト間に信頼関係が築かれます。
攻撃者はこの信頼を利用して、CSRF攻撃により不正なアクセスを試みます。CSRFは、Hostile Linking、Sea Surf、Session Riding、One-click attackなどとも呼ばれます。
CSRF攻撃の特徴は以下の通りです:
CSRF攻撃の発生を最低限に抑えるため、CSRFトークンはランダムに生成される安全で一意なセッショントークンです。ChallengeトークンやSynchronizerトークンが代表例です。
CSRFトークンは、サーバ処理に用いられるHTMLフォームの隠し部分に組み込まれ、エンドユーザのブラウザと共有されます。攻撃者に解読されにくいよう、十分な長さにする必要があります。
CSRF対応のサイトやアプリは、各HTTPリクエストやログインセッションごとに専用のトークンを生成します。
正しいCSRFトークンの検証は攻撃を防ぐ上で重要ですが、検証にはいくつかの要因が影響します。
検証はリクエストの種類により左右されます。例えば、HTTP POSTリクエストは厳しく検証する一方、GETリクエストを拒否する場合もあります。
また、トークンが存在しない場合、そのリクエストは無視されます。
CSRF攻撃を実行するには、次の3条件を満たす必要があります。
これらの条件が揃えば、CSRF攻撃を実行することが可能です。
また、被害者に偽のリクエストを実行させる手法は多種多様です。まずは例を通じ、不正なリクエストの作成方法を見てみましょう。
Example
例えば、Johnがmoney.comサイトを利用してJenaに500ドルを送金する必要があるとします。
このmoney.comサイトは十分なCSRF対策が施されておらず、攻撃者のLeoがこの機会を利用して、Johnが送金しようとする資金を不正に取得しようとします。
そのため、攻撃者Leoは以下の手順で進めます:
次に、異なる状況下でのCSRF攻撃の仕組みを見ていく。
この場合、Johnの送金リクエストは以下のようになります:
GET http ://money.com/transfer.do?acct=JENA&amount=500 HTTP/1.1
攻撃者のLeoは、Johnを介してこれを悪用します。まず、Johnが送金する操作を自分の口座に向けるため、改ざんされたURLを作成します。
Johnの送金コマンドにアクセスし、Jenaの名前を自分のものに置き換え、送金額も変更することができます。改ざん後のコマンドは以下のようになります:
http ://money.com/transfer.do?acct=LEO&amount=5000
このURLでは、Leoが元の送金額を5,000ドルに変更しています。
ここでは、HTMLコンテンツを含むメールや、正規のページに悪用されたURLを埋め込むなどのソーシャルエンジニアリングで、Johnに改ざんURLを読み込ませる手法が用いられます。元のページやURL、スクリプトに非常に似せているため、騙されやすいのです。
もしサイトがPOSTリクエストのみを受け付けるなら、Johnの操作は下記のようになります:
POST http://money.com/transfer.do HTTP/1.1
acct=JENA&amount=500
このリクエストはFORMタグを用いて送信されます:
<form action="http://money.com/transfer.do" method="POST">
<input type="hidden" name="acct" value="Leo"/>
<input type="hidden" name="amount" value="5000"/>
<input type="submit" value="Check my pictures"/</form>
FORMタグの場合、送信ボタンをクリックする必要がありますが、JavaScriptを使って自動送信することも可能です。
GETやPOST以外にも、PUTやDELETEなどのHTTPメソッドが利用されます。PUTリクエストでは、改ざんページやURLにJavaScriptが含まれることがありますが、現代の高度なブラウザは同一オリジンポリシーを適用しているため、PUTやDELETEに対するCSRF攻撃はあまり見られません。
攻撃が成功すると、被害者が意図しない操作が行われ、深刻な影響を及ぼす可能性があります。その被害の大きさは、実行された操作の内容に依存します。
また、対象が企業内で高い権限を持つユーザであれば、被害額はさらに大きくなる恐れがあります。送金、不正なデータ操作、機能の悪用など、様々な被害が考えられます。
例としては:
まず、この攻撃が一般的にどのように設計されるかを理解するところから始めます。
従来のCSRF攻撃は、多数のパラメータを含むカスタムHTMLリクエストを作成する方法ですが、その複雑さと手間のため、高度な攻撃ではほとんど使われません。
多くの攻撃者は、CSRF PoCジェネレーターという最もシンプルな手法を用います。このツールはBurp Suite Professionalに含まれており、以下の手順で利用できます:
攻撃用HTML内容が用意できたら、次はそれを被害者に配信する段階です。
CSRF攻撃の配信方法は反射型XSS攻撃と似ており、攻撃者やテスターは不正な内容をウェブページ、メール、SMSなどに埋め込んで被害者に届けます。対象を絞らない場合は、有名サイトやフォーラムにコメントとして投稿することも可能です。
通常、最も単純なCSRF攻撃は1つのGETリクエストを利用するため、このHTML内容は単一のURLとなる場合があります。例えば、以下のような形です:
<img src="https: //example.com/email/change?email=example@test-csrf.user">
攻撃を成功させるには、被害者にこの画像をクリックさせるだけです。
どのような脆弱性であっても、早期の発見が被害拡大を防ぐ鍵となります。
CSRFを迅速に検出するための主なポイントは以下の通りです:
適切に対策しないと、CSRF攻撃はデータ漏洩、金銭被害、ログイン情報の変更、さらには重要なアプリの制御が失われるなどの問題を引き起こす可能性があります。早期検出に加えて、実施可能な防御策も講じる必要があります。
CSRFトークンによる防御
CSRF攻撃への基本的な対策は、HTTPリクエストが正当に、すなわちアプリのユーザインターフェースを通じて生成されたものであるかを確認することです。これにはCSRFトークンが利用されます。
アプリのセキュリティ担当は、攻撃されやすいサーバ機能の部分を特定し、そのHTMLフォームにCSRFトークンを導入すべきです。
対象のHTMLフォームがセッションクッキーの一部とならないようにし、トークン生成には暗号的に安全な乱数生成器を使用する必要があります。
SameSite Cookie属性の利用
SameSite属性は、Secure FlagやHTTPOnlyと共に、クッキーとクロスサイトリクエストの処理をブラウザに適切に行わせるため、CSRF防御に非常に有効です。
利用可能な値は以下の通りです:
ユーザ操作を活用したCSRF防御
再認証や一回限りのトークン生成、CAPTCHAの導入など、ユーザ操作を促す方法はCSRF防御として最も手軽な策です。これにより攻撃の隙間が狭まり、ユーザ体験も向上します。
ログイン時のCSRF対策
多くの開発者は、ログインフォーム自体にもCSRFが存在し被害をもたらす可能性があることに気づいていません。各ユーザに対してプリセッションを生成し、その中にCSRFトークンを導入することで初期認証を安全にできます。ただし、実際のセッション開始後はプリセッションを削除しないと、セッション固定攻撃のリスクが高まります。
ダブルサブミットクッキー
この方法は、サーバセッションではなくクッキー内に同一のトークン値を保存することでCSRFを防ぐ戦略です。隠しフィールドとクッキーのトークンが一致するか、サーバ側で確認します。
JavaScript部分をCSRF攻撃から守るため、同一オリジンポリシー(SOP)に基づいたカスタムリクエストヘッダーを利用する方法があります。ただし、ブラウザのデフォルト設定ではJavaScriptでのカスタムヘッダー生成は制限されています。
この方法は、UIの変更が不要で、サーバ側の状態を表示する必要もないというメリットがあります。
CSRF攻撃は増加の一途をたどっており、例外はありません。
API利用が拡大し、ウェブやモバイルアプリの開発に不可欠となったことで、APIもCSRF攻撃の標的となっています。APIが攻撃されれば、全体のデジタルソリューションやアプリに影響が及ぶ恐れがあります。
堅牢なAPIセキュリティのためには、APIをCSRF攻撃から守ることが欠かせません。APIを狙うCSRF攻撃は容易に防止できます。
Content-typeがapplicationまたはJSONのAPIリクエストは制限し、CSRF攻撃の可能性を低減させることで、より安全な通信を実現できます。
APIアクセス用トークンはリクエストヘッダーに含め、クッキー依存のCSRFトークンは受け付けないことが重要です。
また、JavaScriptベースのシングルページアプリは、ストレージにクッキーのみを使用し、認証トークンはヘッダーでAPIに転送し、ヘッダーの無いリクエストは拒否するよう設計すべきです。
最新情報を購読