SPAでCSRFが軽視される理由とSameSite Cookie

SPAでCSRF対策が軽視されやすい理由とSameSite Cookieの影響

SPAのセキュリティを考えるとき、多くの開発者はXSSやトークン漏洩には敏感になります。しかしCSRF(クロスサイトリクエストフォージェリ)は後回しにされがちです。

理由は単純で、「トークン認証を使っているから大丈夫」と思われやすいからです。ところが実際には、SPAでもCSRFは成立します。むしろ構成によっては気づきにくくなります。

CSRFとはどんな攻撃か

CSRFは「ユーザーの意思とは無関係に、認証済みの操作を実行させる攻撃」です。典型例は次のようなものです。

ユーザーが銀行サイトにログインしたまま、別のサイトを開いたとします。そのサイトに次のコードが埋め込まれていた場合です。

<img src="https://bank.example/transfer?to=attacker&amount=100000">

ブラウザは単なる画像読み込みとしてリクエストを送ります。しかしCookieは自動送信されます。結果として送金処理が実行されます。

ここで重要なのは、ユーザーがクリックすらしていない点です。ブラウザの「自動Cookie送信」が攻撃の成立条件になります。

なぜSPAでは問題が見えにくいのか

SPAではAPI呼び出しはJavaScriptで行われます。

fetch("/api/profile", { method: "POST" });

このため「フォーム送信がない=CSRFはない」と誤解されがちです。しかしブラウザがCookieを送信するかどうかは、フォームかJavaScriptかではなく、オリジンとCookie属性で決まります。

もしAPIがCookie認証を使っている場合、外部サイトからでもリクエストは送られます。

SameSite Cookieとは何か

この問題に対処するために導入されたのがSameSite属性です。

Set-Cookie: SESSION=abc123; SameSite=Lax

SameSiteは「他サイトからのリクエストにCookieを付与するか」を制御します。

設定 挙動
Strict 他サイトからは一切送らない
Lax 通常の遷移のみ送る
None 常に送る(Secure必須)

近年のブラウザでは、未指定のCookieはLaxとして扱われます。これにより多くの単純なCSRFは防がれます。

SPA特有の落とし穴

ここで問題が発生します。SPAでは次の構成がよくあります。

  • フロント:app.example.com
  • API:api.example.com

この場合、同一サイトでも「別オリジン」です。Cookie送信にはSameSite=Noneが必要になります。

Set-Cookie: SESSION=abc123; SameSite=None; Secure

つまりCSRF防御を弱めないとログインが維持できません。この時点でCSRFのリスクが復活します。

よくある誤解:Authorizationヘッダなら安全?

BearerトークンをAuthorizationヘッダに入れていれば安全だと考えられがちです。確かに外部サイトはヘッダを自由に付与できません。

しかし次の条件では成立します。

  • トークンをCookieに保存
  • 自動送信
  • APIがCookie認証を併用

この場合、CSRF攻撃が可能になります。トークン方式とCookie方式が混在すると、想定外の挙動になります。

対策:CSRFトークン

基本対策はCSRFトークンです。サーバはランダム値を発行し、フォームやリクエストヘッダに含めさせます。

fetch("/api/update", {
  method: "POST",
  headers: { "X-CSRF-Token": token }
});

攻撃者はこの値を取得できないため、正規リクエストを偽装できません。

なぜSameSiteだけでは不十分か

SameSiteは強力ですが万能ではありません。

  • サブドメイン構成
  • OAuthリダイレクト
  • 古いブラウザ

これらでは例外設定が必要になります。その瞬間、防御が弱まります。実務ではSameSiteとCSRFトークンを併用するのが一般的です。

実務で起きやすい事故

SPA移行時に多い問題があります。

  • 開発環境では動く
  • 本番の外部連携で壊れる
  • SameSite=Noneへ変更
  • CSRF対策未実装

この流れで脆弱性が入り込みます。特に決済や設定変更APIで危険です。

まとめ

SPAでCSRFが軽視されやすいのは、画面遷移やフォーム送信が減るため攻撃のイメージが湧きにくいからです。しかし本質は「Cookieが自動送信されるかどうか」です。

SameSite Cookieは強力な防御ですが、クロスオリジン構成のSPAでは例外設定が必要になり、リスクが戻ります。最終的にはCSRFトークンとの併用が安全です。

セキュリティ対策は単独では成立しません。認証方式・Cookie属性・ブラウザ挙動を一体として設計すると、後からの修正が大きく減ります。