こちらの記事は、セキュリティ学習初心者である私みんみんが、学習の備忘録として作成しています。よって 「綿密にいうと異なる」 内容の解説が混じることがございます。
ZooMにて
先輩:今日はクロスサイトリクエストフォージェリ(CSRF)についてやっていきましょう。
CSRFは、 「Cross-Site Request Forgeries(クロスサイト・リクエスト・フォージェリ)」 の略語です。(引用:IPA「安全なウェブサイトの作り方 - 1.6 CSRF(クロスサイト・リクエスト・フォージェリ)」)
『フォージェリ(forgery)』は 「偽造」 という意味ですね。
僕:はい。
先輩:CSRFの攻撃を受けると、「ユーザーが意図していない動作をWebアプリ上で実行させられる」 被害を受けることがあります。
たとえば以下のようなものですね。
- SNS上で身に覚えのない投稿をさせられた
- 勝手にお金を送金されていた
- パスワードを変更された
- 勝手に商品を購入させられていた
僕:うーん…あの正直思うんですけど。これ、XSSと何が違うのかよくわからないんですよね。名前も一部被ってるし。
先輩:わかりますよ。CSRFとXSSってよく似てるので、学習時にも混同しやすいんです。だから今から違いを説明しますね。
CSRFとXSSの違い
先輩:CSRFとXSSの違いとして挙げられるのは、主に以下の2つですね。
- 攻撃される場所
- 攻撃の方法
僕:攻撃される場所ですか…XSSではユーザーのブラウザ画面でしたね。
先輩:そうです。でもCSRFは サーバー(ログイン中ユーザーの権限で) からの攻撃なんですよね。
攻撃の条件は、ユーザーがログイン状態で攻撃ページにアクセスし、何かしらのアクションを起こすことです。
たとえばSNSにログインした状態で他の投稿にあるリンクをクリックしたとします。
この画面覚えてます?
僕:ああ、これXSSの時の…。
先輩:XSSの時はリンクに仕込まれたscriptが作動し、セッションIDを盗んだりしましたよね?
でもCSRFの場合はサーバー側、つまり、バックエンドの方でこんな感じのPOSTリクエストが送信されるんですよ。
POST /user/password/change HTTP/1.1
Host: mysns.example.com
Cookie: session_id=abc123
Content-Type: application/x-www-form-urlencoded
new_password=hacked123
ちなみにこの「Cookie: session_id=abc123」がユーザーのログイン情報です。
僕:ただリンクをクリックしただけなのに、パスワードが勝手に変更されてますね…。しかもセッションIDもバレてるし。
先輩:これややこしいんですけど、XSSの時みたいにセッションIDの値そのものを盗んでるわけじゃなくて。
ユーザーがすでにログインしているのを利用して、 ユーザー本人のふりをしてリクエストを送ってるんです。
つまり、「盗む」のではなく 「ユーザーを利用して使わせている」 という認識をするとわかりやすいかもしれません。
僕:だからこそ、「意図しない動作を実行させられている」ということになるんですね?
先輩:そうですね。
CSRFの主な対策法
先輩:では、CSRFの主な対策法について見ていきましょう。
今回は以下4つを紹介します。
- CookieのSameSite属性を設定する
- POSTメソッドを使用してhiddenフィールドにランダムな値を設定する
- パスワードを再入力してもらう
- 処理実行後に確認メールを送る
CookieのSameSite属性を設定する
先輩:CookieのSameSite属性は、Strict、Lax、Noneの3つを設定できます。
| SameSiteの設定 | 外部サイトからのリクエストでCookieは送信される? |
|---|---|
| Strict | ×(送信されない) |
| Lax | ◯(一部のリクエストで送信される) |
| None | ◯(常に送信される) |
CSRF対策のためには、StrictもしくはLaxを指定します。
POSTメソッドを使用してhiddenフィールドにランダムな値を設定する
先輩:hiddenフィールドに「使い捨ての秘密のカギ(=CSRFトークン)」を隠して送る方法です。
hiddenフィールドはブラウザ画面に表示されない隠しフィールドのことです。
ユーザーには見えませんが、そこに疑似乱数で作ったランダム値を CSRFトークン としてセットしておきます。
そしてリクエストが送られたタイミングでCSRFトークンをチェックし、もし違う場合はリクエストを排除する仕組みです。
僕: 「正規のページからリクエストを送ってないからダメ!」 ということですね。
パスワードを再入力してもらう
先輩:注文確定前など、ユーザーが何かしらしようとする前に自分のパスワードを入力してもらう方法です。
アカウント削除やメールアドレスの変更時にパスワードの再入力が必要なサイト、ありますよね。
僕:あれ、正直だるいなと思ってましたけど…そういう意図があったんですね。
処理実行後に確認メールを送る
処理を実行した後に確認メールを送る方法は、直接攻撃を防ぐわけではないですが、「ユーザーに知らせる」という方法ですね。
CSRFってユーザーには見えないバックで行われる攻撃方法なので、早い段階でユーザーに気づかせることも重要なんです。
僕:なるほどです、色々な方法があるんですね。
参考書籍
- 「体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践」:徳丸 浩 (著)
- 「情報処理教科書 情報処理安全確保支援士 2025年版」:上原 孝之 (著)
