← コラム一覧

CSRF(クロスサイトリクエストフォージェリ)とは|XSS との違い・トークンと SameSite による対策

CSRF(クロスサイトリクエストフォージェリ)の仕組みを、XSS との違いを対比しながら解説。CSRF トークンによる根本対策、SameSite 属性の Lax/Strict/None、情報処理安全確保支援士の午後問題での問われ方まで。

クロスサイトリクエストフォージェリ(CSRF、CWE-352)は、ログイン中の利用者のブラウザに、罠サイトなどから「本人の正規の要求」に見える更新要求を送らせる攻撃です。攻撃者は、被害者が対象サイトにログイン済みであることを利用します。被害者が罠ページを開くと、ブラウザは対象サイトの Cookie を自動で付けて要求を送るため、サーバから見れば本人の操作と区別がつきません。攻撃者は応答を読む必要すらなく、要求が受理されれば目的(設定変更・送金・承認など)を達成できます。

XSS との違い

観点XSSCSRF
悪用するものサイトの出力(画面に注入したスクリプト)利用者の正規のセッション(自動送信される Cookie)
攻撃者が読むもの被害者の画面・Cookie を読める応答を読めなくてよい(送れれば成立)
根本対策出力エスケープリクエストトークンの照合

この違いが重要です。XSS 対策として出力をエスケープしても、CSRF は防げません。CSRF は画面の出力を悪用せず、利用者のセッションを使って正規の要求を送らせる、別の問題だからです。試験でも「XSS 対策では CSRF を防げない理由」を、両者の違いに触れて書かせる形が頻出です。

なぜ通ってしまうのか

ブラウザは、対象サイト宛ての要求に、そのサイトの Cookie を自動で付けます。どのサイトからの遷移かに関わらず送られることがあるため、サーバが「その更新要求が本当に自分の画面(フォーム)から来たのか」を確かめていないと、外部サイトが用意した偽の要求も、本人のセッションで受理されてしまいます。

利用者のブラウザ サイトAにログイン中 罠サイト B 更新要求を送らせる サイト A(更新を受ける) Cookie が付いていれば本人と判断 トークンを照合すると B は値を知らないので 403 で拒否 ① 罠ページを開く ② ブラウザが Cookie を自動で付けて更新要求 ③ 照合していなければ受理されてしまう 攻撃者は応答を読む必要がない。「送れてしまう」ことが成立条件。
図:CSRF の流れ。トークンを照合していれば③で拒否できる

根本対策は CSRF トークンの照合

状態を変える要求(POST・PUT・DELETE など)ごとに、正規のフォームに埋め込んだ使い捨てのトークンと、サーバ側(セッション)が保持するトークンを照合します。外部サイトはこのトークンの値を知り得ないため、偽の要求は一致せず拒否できます。これを Synchronizer Token パターンと呼びます。Cookie とは別に送らせる Double Submit Cookie パターンもあります。

def token_ok():
    # フォームのトークンとセッションのトークンが一致するか
    return request.form.get("_token") == session.get("_token")

@app.post("/admin/applications/<int:aid>/approve")
def approve(aid):
    if not token_ok():
        return "forbidden", 403
    set_status(aid, "approved")

SameSite 属性による緩和

Cookie の SameSite 属性は、別サイトからの遷移で Cookie を送るかどうかを制御します。トークン照合が根本対策であるのに対し、SameSite は多層防御の一枚(緩和策)と位置づけます。

SameSite の値挙動
Strict別サイトからの遷移では一切送らない。最も厳しいが、外部リンクから来た正規の遷移でも送られず、使い勝手に影響することがある
Lax通常のページ遷移(GET)では送るが、別サイトからの POST などでは送らない。多くの CSRF を防ぎつつ実用的で、既定として広く使われる
None常に送る(要 Secure)。クロスサイトで Cookie が必要な場合に限る。CSRF に対しては無防備

その他の対策として、Referer / Origin ヘッダの検証、重要操作での再認証(パスワード再入力)、カスタムリクエストヘッダの要求(単純な form 送信では付けられないヘッダを必須にする)などがあり、トークン照合と組み合わせて使います。

情報処理安全確保支援士 試験での問われ方

午後問題では、更新操作の要求と応答を題材に「なぜ本人の操作として通ったか」「対策」を答えさせる形が多く、トークンによる照合が本命、SameSite 属性は緩和策として扱われます。午前Ⅱでは、CSRF と XSS の違い(出力の悪用か、正規セッションの悪用か)が繰り返し問われます。令和5年度 秋期 午後 問1 では、cookie を別ドメインへ送らせない仕組みとして SameSite が問われました。

同じ問の設問4 は、攻撃者が自分のドメインに同じスクリプトを置いても攻撃が成立しない理由を、ブラウザの仕組みとして 40 字以内で答えさせるものでした。答えは同一オリジンポリシーです。裏を返せば、CSRF が成立するのは「オリジンをまたいでも cookie が送られてしまう」ためであり、同一オリジンポリシーは読み取りは止めても送信は止めない、という境界を押さえているかが問われています。

令和5年度 秋期 情報処理安全確保支援士試験 午後 問1 の問題冊子6ページ。設問4 で、攻撃者が用意したドメインのサイトからでは Web ブラウザの仕組みによって攻撃が成功しない理由が問われている
出典:令和5年度 秋期 情報処理安全確保支援士試験 午後 問1(IPA) 問題冊子 6 ページを掲載

午前Ⅱ では、対策の「効き先」を取り違えていないかが直接問われます。令和6年度 春期 午前Ⅱ 問1 は、CSRF 対策として効果が「ない」ものを選ばせる問題でした。正解は、要求に含まれる "<" や ">" などの特殊文字を "&lt;" "&gt;" に置き換える、という選択肢です。これは XSS 対策であって、CSRF には効きません。CSRF が成立するのは要求の中身が危険だからではなく、正規の cookie が付いたまま要求が届いてしまうからで、文字を無害化しても要求が本物として通ることは変わらないためです。

令和6年度 春期 情報処理安全確保支援士試験 午前Ⅱ の問題冊子3ページ。問1 で、クロスサイトリクエストフォージェリ攻撃の対策として効果がないものが問われている
出典:令和6年度 春期 情報処理安全確保支援士試験 午前Ⅱ 問1(IPA) 問題冊子 3 ページを掲載(同じページに問2 も載っています)

残りの選択肢は、いずれも CSRF に効く対策です。重要操作の都度パスワードを入力させる(再認証)、ログイン後に毎回異なる値を応答に含めて要求ごとに照合する(CSRF トークン)、Referer で正しいリンク元からの遷移かを確認する。この並びは、そのまま対策の一覧として覚えてしまってよい形になっています。

IPA 公式 PDF:令和6年度 春期 午前Ⅱ問題(問1 が CSRF 対策) ↗解答例と採点講評も公式サイトで公開されています。

IPA 公式 PDF:令和5年度 秋期 午後問題(問1 に SameSite が登場) ↗本文はこの公式 PDF でご覧ください(アプリ内には転載していません)。

確認しておきたいこと

演習(支援士日誌)で手を動かす →