「鍵をかけても泥棒が入る?」XSSとCSRFの恐ろしい共演と、その防ぎ方
こんにちは!セキュリティの世界へようこそ。
日々、開発の現場で「セキュリティ対策はバッチリ!」と思っていても、実はその裏で攻撃者は「どうすればその対策をすり抜けて、あなたの家(Webサイト)に忍び込めるか」を常に考えています。
今日は、初心者の方が特に混乱しやすい「XSS(クロスサイトスクリプティング)」と「CSRF(クロスサイトリクエストフォージェリ)」という、名前は似ているけれど全く別の二つの攻撃が、結託して最強の泥棒に変貌するお話をお届けします。
—
1. まずは「泥棒の例え」で理解しましょう
Webセキュリティを考えるとき、家を想像するのが一番わかりやすいです。
- CSRF(泥棒のなりすまし):
あなたになりすまして、勝手にあなたの家の「合鍵(セッション)」を使って、銀行送金の手続きをしたり、設定を変えたりする攻撃です。
- Anti-CSRFトークン(特殊な鍵):
CSRFを防ぐために、Webサイトは「あなた本人しか知らないはずの、使い捨てのパスワード(トークン)」を要求します。これがあれば、泥棒は合鍵だけでは家の中に入れなくなります。
- XSS(鍵のコピー取り):
悪意のあるスクリプト(プログラム)をWebサイトに埋め込み、閲覧者のブラウザ上で勝手に動かします。これにより、あなたの机の上に置いてあるはずの「Anti-CSRFトークン」を、コソッと盗み見られてしまうのです。
つまり、「XSSでトークンを盗む」→「盗んだトークンを使ってCSRFを仕掛ける」という最悪のコンボが成立してしまうわけです。
—
2. 攻撃はどうやって成立するのか?(メカニズム)
攻撃者は、あなたのサイトの「掲示板」や「コメント欄」に、こんな罠を仕掛けます。
ユーザーがこのページを開いた瞬間、ブラウザはこのスクリプトを実行し、「あなたになりすますためのパスポート(トークン)」が攻撃者の手元に渡ります。
あとは、攻撃者はそのトークンを使って、あなたのサイトに対して「パスワード変更」や「送金」といったリクエストを送るだけです。サーバー側は「お、正しいトークンが添えられているな。じゃあ本人に違いない!」と、まんまと騙されてしまうのです。
—
3. 「一歩ずつ」対策を学んでいきましょう!
この恐怖の連鎖を止めるには、両方の入り口を塞ぐことが重要です。
対策①:XSSを根絶する(そもそも盗ませない)
すべての入力値は「疑わしいもの」として扱い、正しく無害化(エスケープ)しましょう。
- HTMLエスケープ:
<を<に変換するなど、スクリプトとして実行させない処理を徹底します。 - Content Security Policy (CSP): ブラウザに対して「許可された場所以外からのスクリプトは実行するな!」と命令する最強の盾です。
HTTPレスポンスヘッダーの設定例
信頼できるドメインからのスクリプトのみ許可する
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com;
対策②:Cookieに「絶対に触らせない」属性を付ける
トークンを盗まれないための、一番手軽で強力な方法です。Cookieには HttpOnly という魔法の属性があります。
Set-Cookieヘッダーの設定例
Set-Cookie: session_id=abc123xyz; HttpOnly; Secure; SameSite=Strict
- HttpOnly: 「JavaScriptからはこのCookieを絶対に読み取れないようにする」という設定です。これさえあれば、万が一XSSが起きても、トークンを盗まれるリスクを大幅に下げられます。
- SameSite=Strict: 「別のサイトから来たリクエストには、このCookieを渡さない」という設定で、CSRFを強力にブロックします。
---
最後に:完璧を目指さず、まずは「設定」から
セキュリティは「これ一つやれば安心」という銀の弾丸はありません。ですが、今回ご紹介した 「HttpOnly属性」 や 「CSPヘッダー」 を見直すだけで、あなたのサイトの守備力は劇的に向上します。
「難しそう」と後回しにするのではなく、まずは開発しているサイトのレスポンスヘッダーを確認してみてください。「あ、これ付いていないな」と気づくことが、強固なセキュリティへの第一歩です。
一緒に、より安全なWebの世界を作っていきましょう!何か分からないことがあれば、いつでもまた聞きに来てくださいね。
コメント