ITの教科書検索
入門読了 約12分

CSRFとは ― 仕組みとトークン・SameSiteの対策

CSRFは、罠のページを開いただけで、ログイン中のサイトに本人の操作として要求を送らせる攻撃です。トークンやSameSiteがどこで止めるかを図で比べられます。

目次
  1. CSRFとは、ログイン中のブラウザに偽の要求を送らせる攻撃
  2. CSRFの攻撃の流れ
  3. 動かして確かめる:対策を切り替えて、偽の要求を送る
  4. CSRFとXSSの違い
  5. CSRFの対策
  6. SameSite属性だけでは足りない理由
  7. 利用者の側でできること
  8. 練習問題
  9. 参考にした資料

CSRFとは、ログイン中のブラウザに偽の要求を送らせる攻撃

CSRFは、別のサイトのページを開いただけで、ログイン中のサイトへの要求を利用者のブラウザに送らせる攻撃です。ブラウザは、その要求にもログイン中のCookieを付けます。そのため、サイトは本人の操作として処理してしまいます。

たとえば、通販サイトにログインしたまま、メールのリンクから罠のページを開いたとします。それだけで本人の知らないうちに、設定の書き換えや掲示板への書き込み、意図しない購入や送金が起こりえます。CSRFはCross-Site Request Forgeryの略です。日本語ではクロスサイトリクエストフォージェリと呼びます。

CSRFの攻撃の流れ

利用者がexample.comにログインしたまま、攻撃者の用意したexample.netのページを開いたとします。このページには、example.comの設定を変えるフォームが隠してあります。フォームは、ページを開いた直後に自動で送信されます。

罠のページexample.netexample.comあての隠したフォーム① 罠のページを開く② 自動送信のフォームが届くブラウザexample.comにログイン中Cookie: SID=31d4d96e407aad42③ 偽の要求にCookieが自動で付く正規のサイトexample.comCookieが合う → 本人の操作として処理
点線の枠は、攻撃者が用意したページです。色を付けた③の要求は、利用者が送ったつもりのないものです。それでもブラウザは、送り先のexample.comに合うCookieを付けるので、正規のサイトは本人からの要求と区別できません。

ブラウザは、送り先のサイトに合うCookieを、要求に自動で付けます。CookieのSameSite属性で止めていなければ、別のサイトのページから送られた要求にも付けます。そのため、サーバがCookieだけで利用者を確かめていると、本人の操作と偽の要求を区別できません。

攻撃が成り立つ条件

  • 利用者が、正規のサイトにログインしている
  • サイトが、Cookieなどブラウザが自動で送る情報だけで、利用者を確かめている
  • 要求の中身を、攻撃者が前もって組み立てられる

IPAの「安全なウェブサイトの作り方」によると、注意が必要なのは、Cookieでセッションを管理するサイトです。Basic認証やSSLクライアント認証を使うサイトも同じです。どれも、一度認証すると、ブラウザが以降の要求に認証の情報を付けて送ります。

攻撃者は、偽の要求への応答を受け取れません。応答は利用者のブラウザに返り、罠のページからは読めないためです。そのため、CSRFは設定の変更や書き込みのように、サイトの状態を変える処理を狙います。Webの安全性に取り組む団体OWASPも、そう説明しています。

動かして確かめる:対策を切り替えて、偽の要求を送る

次の図は、登録メールアドレスの変更を例に、攻撃の流れを4段に分けて示します。対策を切り替えると、偽の要求が通るか止まるかを同じ段で比べられます。

対策
STEP 1 / 4
処理する場所:正規のサイト(example.com)
Set-Cookie: SID=31d4d96e407aad42; Secure; HttpOnly
1段目:正規のサイトにログインする
利用者がexample.comにログインすると、サーバはセッションIDをCookieで渡します。ブラウザは、このCookieを保存します。SameSite属性は付けていません。
ブラウザが、ログイン中のCookieを持つ

CSRFトークンとOriginの確認では、Cookieが付いて届いても、サーバが4段目で止めます。SameSite=Laxでは、3段目でブラウザがCookieを付けないので、ログインしていない要求として扱われます。止まる場所が違うのは、確かめるのがサーバかブラウザかが違うからです。

CSRFとXSSの違い

XSSでは、攻撃者のスクリプトが、正規のサイトのページの中で動きます。CSRFでは、正規のサイトのページで攻撃者のスクリプトは動きません。CSRFで攻撃者ができるのは、ブラウザに要求を送らせることだけです。

比べる点XSSCSRF
攻撃者が送り込むものスクリプト正規のサイトへの要求
正規のサイトのページで、攻撃者のスクリプトが動くか動く動かない
攻撃者が応答を読めるかスクリプトで読める読めない
欠陥のある処理ページへの出力要求が本人の意図か確かめない処理
根本的な対策出力するときのエスケープトークンなどで本人の画面からの要求か確かめる

2つの攻撃には、別々の対策が必要です。エスケープでXSSを防いでも、CSRFは防げません。逆に、XSSの脆弱性があると、ページの中で動くスクリプトがトークンを読み取れます。OWASPは、XSSがあればCSRFの対策はすべて破られうると注意しています。

CSRFの対策

対策の考え方は、要求が本人の操作から来たものかを、Cookie以外の手がかりで確かめることです。IPAとOWASPが挙げる主な方法を、何を確かめるかで並べます。

対策確かめること位置づけ
CSRFトークン正規の画面で渡した乱数が、セッションに覚えた値と一致するか主な対策
パスワードの再入力処理の直前に、本人がパスワードを入れたか主な対策。重要な操作に絞って使う
Origin・Refererの確認要求が、自分のサイトのページから始まったかIPAはRefererの確認を根本的解決の1つ、OWASPは追加の対策
SameSite属性別のサイトから始まった要求に、Cookieを付けないか追加の対策

Webアプリのフレームワークには、CSRFの対策が組み込まれているものがあります。OWASPは、組み込まれていれば、まずその機能を使うよう勧めています。

CSRFトークンを照合する

サーバは、変更の画面を返すとき、推測できない乱数をフォームの隠し項目に入れます。この乱数をCSRFトークンと呼びます。サーバは同じ値をセッションの情報として覚えておき、変更の要求が届いたら照合します。一致したときだけ処理します。

IPAは、この方法を根本的解決に挙げ、トークンを予測困難な乱数で作るよう求めています。トークンを入れる要求はPOSTにします。GETにするとトークンがURLに入るためです。URLは、直前のページのURLを伝えるRefererヘッダで、別のサイトに送られることがあります。

OWASPは、トークンを利用者のセッションごとに変え、秘密にしておくよう求めています。この方式では、トークンをCookieで送らず、URLやサーバのログにも残しません。推測できない値で要求を本人のブラウザに結び付ける考え方は、OAuthのstateにも使われています。

重要な操作では、パスワードを入れ直させる

処理を実行する直前の画面で、パスワードをもう一度入力させる方法です。攻撃者はパスワードを知らないので、罠のページからの要求では処理が通りません。IPAは、これも根本的解決の1つに挙げています。

ただし、画面の作りを変える必要があり、利用者の手間も増えます。OWASPは、再認証のような利用者の操作を求める対策を、送金などの重要な操作に絞って使うよう勧めています。

要求の出どころをOrigin・Refererで確かめる

オリジンは、スキーム・ホスト名・ポート番号の組で表す、ページの出どころです。ブラウザは、別のオリジンへのPOSTの要求に、Originヘッダを付けます。Originヘッダには、要求を始めたページのオリジンが入ります。罠のページのスクリプトからは、この値を変えられません。

OWASPは、Originの値と自分のオリジンを完全一致で比べるよう勧めています。Originが無ければRefererで比べます。example.com.example.net のように、前の部分だけが合う名前を通してはいけません。

どちらのヘッダでも確かめられず、トークンなどほかの対策も通らなければ、要求を拒否します。Originの値は、別のオリジンへのリダイレクトなどで null になることがあります。null を、自分のサイトからの要求として扱ってはいけません。

IPAは、Refererの確認を根本的解決の1つに挙げています。ただし、Refererを送らない設定の利用者は、サイトを使えなくなることがあります。同じサイトの中に攻撃者が罠を置ける場合も、効き目が下がります。

新しいブラウザは、Sec-Fetch-Siteヘッダで、要求が別のサイトから始まったかをサーバに伝えます。MDNは、このヘッダで別のサイトからの要求を断る方法を、主な対策の1つに挙げています。OWASPも、新しいブラウザだけを相手にするサイトなら、この方法に頼れるとしています。

状態を変える処理をGETで受け付けない

OWASPとMDNは、設定の変更などの処理にGETを使わないよう勧めています。GETの要求は、リンクや画像の読み込みからでも送らせられます。次の節で説明するとおり、SameSite=Laxも、ページ全体の移動ならGETの要求にCookieを付けます。

保険として、重要な操作をしたら、登録済みのメールアドレスに通知する方法もあります。攻撃は止められませんが、利用者が早く気づけます。IPAは、この通知を保険的対策に挙げています。

SameSite属性だけでは足りない理由

SameSiteは、別のサイトから始まった要求に、Cookieを付けるかどうかを決める属性です。Strict・Lax・Noneの3つの値の意味は、Cookieの記事で説明しています。Laxにすると、前の図のように、別のサイトのフォームから送られたPOSTにはCookieが付きません。

それでも、SameSiteはトークンの代わりになりません。OWASPによると、SameSiteは追加の対策としては役立ちます。しかし、多くの場合は本来の対策の代わりになりません。そのうえで、トークンと組み合わせるよう求めています。

Cookieの仕様であるRFC 6265には、改訂版の草案があります。この草案も、Laxは追加の防御として妥当でも、CSRF全般への堅い防御にはならないとしています。

  • Laxは、リンクやGETのフォームによるページ全体の移動なら、別のサイトからの要求にもCookieを付けます。設定の変更をGETで受け付けるサイトは守れません。
  • SameSiteが区別するのは、オリジンではなくサイトです。MDNによると、同じドメインのサブドメインどうしは同じサイトとして扱われます。
  • SameSiteを書かないCookieの扱いは、ブラウザで違います。FirefoxとSafariは、既定ではLaxとして扱いません。

利用者の側でできること

CSRFの対策は、主にサイトを作る側の仕事です。それでも、利用者の側で、攻撃が成り立つ条件を減らせます。

CSRFが狙うのは、ログイン中の利用者だけが使える処理です。ネットバンキングや通販サイトを使い終わったら、ログアウトしておきます。ログイン中のまま、メールやSNSの見知らぬリンクを開かないことも備えになります。

サイトから、身に覚えのない変更の通知が届いたら、すぐにパスワードや設定を確かめます。前の節で説明した通知は、利用者が気づいて初めて役に立ちます。

練習問題(全6問)

Q1CSRF(クロスサイトリクエストフォージェリ)の説明として正しいものはどれ?
Q2CSRFトークンで偽の要求を止められる理由として正しいものはどれ?
Q3CookieにSameSite=Laxを付けたときの説明として正しいものはどれ?
Q4XSSとCSRFの違いとして正しいものはどれ?
Q5重要な操作の直前に、パスワードをもう一度入力させる対策の効果として正しいものはどれ?
Q6利用者の側でできるCSRFへの備えとして適切なものはどれ?

選んでから「採点する」を押すと、解説つきで答え合わせができます。

参考にした資料

関連記事

おすすめの本 PR

セキュリティとデータベースは、基本情報技術者試験の対策本でまとめて学べます。

目的別の本の選び方を見る

セキュリティの記事を続けて読む

セキュリティ 全37本中10本目