あなたのWebサイトが「偽の署名」で乗っ取られる?CSRF対策の切り札「ダブルサブミットクッキー」を解説します
こんにちは。現場で泥臭いインシデント対応を続けていると、「なぜこんな単純な攻撃で?」と驚くような被害に何度も遭遇します。今日は、Webアプリ開発者なら避けては通れない「CSRF(クロスサイト・リクエスト・フォージェリ)」という、ちょっと厄介な攻撃と、そのスマートな対策についてお話しします。
専門用語だらけで難しく感じるかもしれませんが、大丈夫。まずは身近な「家の防犯」に例えて、一歩ずつ紐解いていきましょう。
—
1. CSRF攻撃のメカニズム:泥棒の「なりすまし」手口
CSRFは、日本語で「クロスサイト・リクエスト・フォージェリ」と呼びます。直訳すると「サイトをまたいだ偽のリクエスト」です。
想像してみてください。あなたは自分の家の玄関(Webサイト)に、「鍵を開けて家の中を掃除してくれ」と書いたメモ(リクエスト)を置いておきます。すると、近所の悪巧みをしている泥棒が、あなたの筆跡を真似て「(実は泥棒の家である)Bさんの家も掃除してくれ」という偽のメモを、あなたの代わりに玄関のポストに入れてしまったとしたら……?
Webブラウザは、一度ログインすると「この人は本人だ」という情報をCookieとして持っていますよね。攻撃者は、あなたがログインしている隙に、あなたが意図しない操作(パスワード変更や送金など)を、あなたのブラウザ経由で勝手に実行させてしまうのです。
—
2. 「ダブルサブミットクッキー法」という賢い防衛策
通常、CSRF対策といえば「サーバー側にトークンを保存する」のが王道ですが、サーバーに状態を持たせない(ステートレスな)マイクロサービスのような環境だと、毎回サーバーに確認しに行くのは手間ですよね。
そこで登場するのが「ダブルサブミットクッキー法」です。
仕組みを例えると?
これは、玄関の鍵の仕組みを少し変えるようなものです。
1. あなたのポケットに「ランダムな合言葉(トークン)」を入れます(Cookie)。
2. 家の掃除をお願いするメモにも、同じ「ランダムな合言葉」を書いて提出します(リクエストパラメータ)。
サーバーは玄関で、「ポケットの合言葉」と「メモの合言葉」が一致しているかだけを確認します。泥棒はあなたのポケットの中身(Cookie)を盗み見る権限がないため、正しい合言葉が書かれたメモを作成することができません。これで、偽のメモを弾くことができるわけです。
—
3. 実装のポイント:コードで見てみよう
例えば、JavaScriptを使ってリクエストを送る場合、以下のようなイメージになります。
// 1. クッキーからトークンを読み取る(ブラウザが自動送信するCookieの値)
const csrfToken = getCookie(‘csrf_token’);
// 2. HTTPヘッダーにトークンを仕込む(サーバー側はここをチェックする)
fetch(‘/api/update-profile’, {
method: ‘POST’,
headers: {
‘Content-Type’: ‘application/json’,
// X-XSRF-TOKENというヘッダー名が一般的です
‘X-XSRF-TOKEN’: csrfToken
},
body: JSON.stringify({ name: ‘新しい名前’ })
});
サーバー側では、「リクエストヘッダーの値」と「Cookieの値」が一致しているかを照合するだけでOKです。データベースに値を保存する必要がないため、非常に高速に処理できますね。
—
4. 盲点:サブドメインからの攻撃にご用心!
さて、ここで一つだけ注意点があります。これがプロのセキュリティ担当者が一番気にするポイントです。
「Cookieはサブドメイン間で共有されることがある」という仕様です。
もし、あなたのメインサイトが app.example.com で、攻撃者が同じサーバーの malicious.example.com(サブドメイン)を乗っ取った場合、攻撃者はメインサイトのCookieを書き換えることができてしまいます。
どう対策すればいい?
- Cookieの属性を厳格にする:
SameSite=StrictやSameSite=Laxを設定し、Cookieが安易に外部サイトへ送られないようにしましょう。 - Secure属性をつける:
Secure属性を付与して、暗号化されたHTTPS通信でのみCookieが送られるように徹底してください。 - サブドメインの管理を徹底する: 「サブドメインだから安全」という油断が一番の穴になります。
—
最後に:セキュリティは「完璧」を目指さない
セキュリティの世界では、「100%安全」な状態はありません。今回ご紹介したダブルサブミットクッキー法も、最強の盾ではなく「泥棒がわざわざ面倒なことをしてまで襲わない程度のハードル」を適切に設置するものです。
まずは、自分の開発しているサイトで「本当にこのリクエストは本人が送ったものか?」という視点を持つこと。そこからすべてが始まります。
難しく考えすぎず、まずはブラウザの「開発者ツール」を開いて、どんなCookieが飛んでいるか眺めてみることから始めてみませんか?それが、一流のエンジニアへの第一歩です。応援していますよ!
コメント