Webアプリケーション攻撃

SameSite属性 さめさいとぞくせい

CSRFCookieクロスサイトリクエストフォージェリセキュリティHTTPヘッダーブラウザ
SameSite属性について教えて

簡単に言うとこんな感じ!

Cookieに付けられる「よそのサイトからのリクエストには渡さないでね」という指示票だよ。悪意あるサイトが「あなたのログイン情報を使って勝手に操作する」CSRF攻撃をブラウザ側でブロックしてくれる仕組みなんだ!


SameSite属性とは

SameSite属性とは、WebブラウザがCookieを送信する条件を制御するための設定値で、クロスサイトリクエストフォージェリ(CSRF) 攻撃を防ぐためにHTTPレスポンスヘッダー内のSet-Cookieに付与されます。2016年にGoogleのエンジニアによって提案され、現在は主要ブラウザすべてで対応済みの重要なセキュリティ機能です。

通常のCookieは、どのサイトからのリクエストであっても、対象ドメインへのリクエストに自動的に付与されます。これを悪用したのがCSRF攻撃です。SameSite属性を使うと、「同じサイト(SameSite)からのリクエストにしかCookieを送らない」 というルールをブラウザに課せるようになります。

設定はサーバー側のレスポンスヘッダーに一行追加するだけで機能し、アプリ側のコード変更を最小限に抑えながらセキュリティを強化できる という点で非常に実用的な対策です。


SameSite属性の3つの値

SameSite属性には StrictLaxNone の3つの値があり、それぞれCookieを送るタイミングが異なります。

クロスサイトGETクロスサイトPOST特徴
Strict送らない送らない最も厳格。外部リンクから来ても送らない
Lax送る(トップレベルナビゲーションのみ)送らないバランス型。Chrome の既定値(2020年〜)
None送る送る制限なし。必ず Secure 属性とセットが必要

覚え方

厳格なStrictさん・バランスのLaxくん・なんでもOKなNoneさん」と人物にたとえると覚えやすいです。実務では Lax が現実的な出発点になることが多いです。

Laxが「送る」ケース(トップレベルナビゲーション)

以下のような「ユーザーが直接リンクをクリックして遷移する」操作はLaxでもCookieが送られます:

✅ Laxで送られるケース
  ブラウザのアドレスバーに直接入力
  <a href="..."> リンクのクリック
  GETリクエストのフォーム送信(method="get")
  window.location.href による遷移

❌ Laxで送られないケース
  <form method="post"> による送信(CSRF攻撃の典型的な手口)
  <img src="..."> / <iframe src="..."> などによる埋め込みリクエスト
  fetch() / XMLHttpRequest によるクロスサイトリクエスト

歴史と背景

  • 2013年頃 — CSRFはOWASP Top 10に毎回ランクインする重大な脅威として認識される
  • 2016年 — GoogleのエンジニアがSameSite属性の草案を提案。ChromeとFirefoxが実験的に実装開始
  • 2019年 — IETF(インターネット技術標準化機関)がRFC草案として標準化作業を開始(RFC 6265bis)
  • 2020年2月Chrome 80がSameSiteのデフォルト値を None から Lax に変更。既存のCookieに属性がない場合も自動的にLax扱いに。業界に大きなインパクトを与えた
  • 2020年以降 — Firefox・Safari・Edgeも順次 Lax デフォルトを採用。Noneを使いたい場合は明示的に Secure とセットで指定が必須となる
  • 現在 — SameSite属性はCSRF対策の「まず最初にやること」として広く普及

CSRFとSameSite属性の関係

CSRFとSameSite属性の関係を図で整理します。

CSRF攻撃とSameSite属性による防御 ⚠ SameSite未設定(攻撃成立) ① ユーザーが銀行サイトにログイン → Cookieが発行される ② 悪意あるサイトにアクセス → 隠しフォームでPOSTリクエスト送信 ③ Cookieが一緒に送られてしまう → 銀行サーバーが正規リクエストと誤認 ④ 不正送金・設定変更が実行される 攻撃成立 💀 ✅ SameSite=Lax(攻撃をブロック) ① ユーザーが銀行サイトにログイン → SameSite=LaxなCookieが発行される ② 悪意あるサイトにアクセス → 隠しフォームでPOSTリクエスト送信 ③ ブラウザがクロスサイトと判断 → Cookieを送信しない! ④ 未認証扱いでリジェクト 攻撃失敗 🛡 属性を 付けるだけ

Set-Cookieヘッダーの書き方

# SameSite=Lax(推奨・現在のブラウザデフォルト)
Set-Cookie: sessionId=abc123; Path=/; HttpOnly; SameSite=Lax

# SameSite=Strict(最も厳格)
Set-Cookie: sessionId=abc123; Path=/; HttpOnly; SameSite=Strict

# SameSite=None(外部サービス連携など。Secureが必須)
Set-Cookie: sessionId=abc123; Path=/; HttpOnly; Secure; SameSite=None

SameSite属性だけで十分?

SameSite属性はCSRF対策として非常に有効ですが、単独での完全な対策には限界もあります

対策有効性備考
SameSite属性ブラウザ側で制御。設定が簡単
CSRFトークンサーバー側で制御。古いブラウザにも有効
Originヘッダー検証サーバー側でリクエスト元を検証
Refererヘッダー検証プライバシー設定で送られないことも

実務では SameSite属性+CSRFトークン を組み合わせて多層防御とするのがベストプラクティスです。


関連する規格・RFC

規格・RFC番号内容
RFC 6265HTTPのCookie仕様(Cookieの基本定義)
RFC 6265bis(ドラフト)SameSite属性を含むCookie仕様のアップデート版
OWASP CSRF Prevention Cheat SheetCSRF対策のベストプラクティス集。SameSiteも推奨

関連用語