記事アップデート
- 【2020/2/2】SameSiteのデフォルト変更が適用されるのは2月17日の週になりました。
- 【2020/2/6】2月17日の月曜日はアメリカでは祝日であり、そこは避けられるとのことです。(SameSite Updates 2/3更新内容より)
- 【2020/4/7】COVID-19の影響によりSameSiteの動きを一時的に元に戻し、夏を目途に再開するとのことです。
- 【2020/6/2】7/14のChrome 84リリースと同時に、再び段階的にロールアウトされていく予定です。(SameSite Updates 5/28)
- 【2020/7/17】Chrome 84がリリースされました。80、81、83にも段階的に適用されます。(SameSite Updates 7/14)
- 【2022/1/19】Firefox 96.0からSameSiteがデフォルトでlaxになりました。(Firefox リリースノート)
Chrome 80で何が変わるのか
2020年2月4日にGoogle Chrome 80がリリース予定されています。
Google Developersの 新しい Cookie 設定 SameSite=None; Secure の準備を始めましょう の記事にあるように、
このバージョンから以下のように変わります。
- Chrome 79まで
- SameSiteが未指定の場合
None
と同じになる。
- SameSiteが未指定の場合
- Chrome 80から
- SameSiteが未指定の場合
Lax
と同じになる。 - SameSiteに
None
を指定する場合は、Secure属性が必須となる。
- SameSiteが未指定の場合
※Secure属性とは、HTTPS上だけで読み取りができるCookieです。
なぜ変わるのか
先のGoogle Developersのブログに書いてあることをざっくりまとめると以下のようになります。
- SameSiteを使えるようにした。
Lax
かStrict
を指定すればCSRFは防げる。 - でも誰も使っていないので大多数のサイトにCSRFの脅威がある。
- ならばデフォルトを
Lax
にしてしまえ。そうすれば大多数のサイトはCSRFについて安全だ。 - クロスサイトで使いたきゃ明示的に
None
を指定した上でSecure属性を付ければいい。
SameSiteとは?
CookieのSameSite属性はStrict
Lax
None
の3つの値を取ります。
値により、クロスサイトでの通信でCookieの送信を制御します。
設定値
- Aサイト…Cookieを発行したサイト
- Bサイト…Aとは別ドメインのサイト
設定値 | 効果 |
---|---|
Strict | Aサイトに対し、Bサイトからどのようなリクエストがあっても、発行したサイトでCookieヘッダーに含めない (Cookieを使用しない) |
Lax | Chrome 80からのデフォルト値。 Aサイトに対し、BサイトからのPOSTや画像読み込み、XHR、iframeでのリクエストでは発行したサイトでCookieヘッダーに含めない (Cookieを使用しない) GETであればCookieヘッダーに含める (Cookieを使用する) |
None | Chrome 79以下や他ブラウザのデフォルト値。 Chrome 80からこの値を設定する場合、Secure属性も必須となる。 Aサイトに対し、Bサイトからどのようなリクエストがあっても、発行したサイトでCookieヘッダーに含める (Cookieを使用する) |
図にすると以下のようになります。
Strict
Lax
外部サイトからのアクセスはGETリクエストのときだけCookieを送る。
None
従来通りの動き。
【追記】なおChrome 80以降でSecure属性を付けずSameSite=Noneを指定した場合、set-cookie自体が無効になります。
セキュリティ上の効果
CSRF対策になります。
CSRF (クロスサイト・リクエスト・フォージェリ) とは、
WEBサイトがユーザー本人の意図した動作であることを検証していないためにおこる脆弱です。
- たとえば会員の退会ページを
https://example.com/mypage/delete/
で用意し、
ボタン操作でsubmit=1
が送信されて退会処理が実行される仕様の場合、
パラメータが誰でもわかるので、外部に用意された悪意のあるフォームからも
同じパラメータで送信することができます。 - ログイン済みの会員ユーザーがその状態で悪意のあるフォームを操作してしまうと
意図せず退会されていまいます。
CSRF対策でよくある方法は、
本人しかわからないパラメータ(ランダム文字列など)を発行して一緒に送信することで
ボタン操作が本人にひもづく動作であることを確認しています。
- SameSite (
Lax
orStrict
)の場合、ユーザー本人にひもづかないようにしてしまうことでCSRF対策としています。
ユーザー本人かどうかWEBサイトが知るにはCookieに識別情報に持つことで実現しているのですが、
外部の悪意のあるフォームなどからの送信でそのCookieを付けないようにすれば
WEBから見ればログインしていない人が退会しようとしていますので、エラーとなります。
このようにCSRFに一定の効果があることから、Chrome 80からデフォルトをLax
として扱うようになります。
対策
特に何もしなくても大丈夫なサイト
- 特にCookieを発行していないサイト。
- 外部からPOSTや画像のロード、XHR、iframeでの呼び出しが無いサイト。
- 外部からPOSTなどされてくるけど、特にCookieが読み込めなくても問題ないサイト。
上記以外のサイトでは対策が必要になりそう
SameSite=None
を付けた上でSecure属性を付与をすることで、従来通りの動作になります。
Secure属性を付けるためにはHTTPSである必要があるため、HTTPのサイトは証明書を取得しSSL/TLSに対応する必要があります。
画像やXHR、iframeなどを使ってユーザートラッキングのCookieを発行しているサイト
ECやサービス系の会員サイトで、決済や認証などで外部サービスを利用し、外部サイトからPOSTで戻ってくるサイト
- 決済でいえばクレジットカードの3Dセキュアが本人認証のためにイシュアのサイトにリダイレクトし、
戻るときにPOSTしている可能性があります。 - ユーザー識別をCookieで行っている場合、外部サイトから戻ってきたときにユーザーが識別できなくなります。
つまり大抵はこういった外部サービスとの連携処理がエラーになります。
ECサイトであれば注文ができないことになるので損失が出る可能性があります。 - ユーザー識別CookieはファーストパーティCookieですが、SameSiteは特にファーストパーティ、サードパーティかは区別しません。
「サードパーティCookieだけだから関係ないんじゃない?」と誤解している人も周りに多くいました…。
テスト方法
- Chrome 79以下では
chrome://flags/
を開き、以下をEnabled
にしてブラウザを再起動します。
注意点
- ただしChrome 78, 79では想定通り動いたり動かなかったりするような動作をします。
- これはChrome 78以降は「POST+Lax」のとき介入サポートとして、
Laxであっても2分間はCookieを送信するというChrome独自の動作によるものです。 - この2分間の介入サポートは将来的に削除され、本来のLaxの動きになる予定です。
- テストする際には2分待ちましょう。
コマンドラインで--enable-features=ShortLaxAllowUnsafeThreshold
を付けると変えられるみたいです。(未検証) - Chrome Platform Status - Cookies default to SameSite=Lax より。
この2分間という介入サポート、かえって混乱を招くのでは…(ボソッ
【追記】2分間について補足を追加しました。
まとめ
-
2020年2月4日リリース予定のChrome 80からSameSite属性のないCookieは
Lax
になる。 - 外部からPOSTや画像のロード、XHR、iframeでの呼び出しでCookieは付かなくなる。
- つまりCookieを使った会員識別をしている際、外部からアクセスされると識別できなくなる。
- サードパーティCookieを使っているサービスのほか、ファーストパーティCookieでも
ECやサービス系の会員サイトで外部と画面上で連携している場合は早急に確認と対策が必要。
追記
2020/02/02
The Chromium Projects - SameSite Updates に1/30に更新された内容によると
2/4のStableリリースと同時に適用されず、2/17の週からごく一部のユーザーに適用され、段階的に適用を拡大するようです。
(Antoine Bourlonさん、情報ありがとうございます)
2週後ろ倒しになり、なおかつ段階的な適用拡大ということで大きな混乱は避けられそうです…。
The SameSite-by-default and SameSite=None-requires-Secure behaviors will begin rolling out to Chrome 80 Stable for an initial limited population starting the week of February 17, 2020. We will be closely monitoring and evaluating ecosystem impact from this initial limited phase through gradually increasing rollouts.
2020/02/03
iOS 12とmacOS 10.14のSafariでは
SameSiteにNone
もしくは無効な値
を指定すると**Strictとして扱われてしまいます**。
( @keitaromiura-link さん、情報ありがとうございます)
このためChrome 80以降への対応でNone
を付けつつ、これらのSafariでも動作させたい場合は
こちらのコメントにあるように正規表現でユーザーエージェントで判定し出し分ける方法があります。
コメントの例ですと下記にマッチするものはSameSiteを送信しない、としています。(あくまで例なのでよく検証ください)
^.*iPhone; CPU iPhone OS 1[0-2].*$
^.*iPad; CPU OS 1[0-2].*$
^.*iPod touch; CPU iPhone OS 1[0-2].*$
^.*Macintosh; Intel Mac OS X.*Version\/1[0-2].*Safari.*$
出し分けをしないという方法もありますが、StatCounterを見ると2020年2月現在で
- iOS 13より前のバージョンのシェア…iOS内で約23% (iOS自体は全OSの約31%なので全体の約7%)
- macOS 10.15より前のバージョンのシェア…macOS内で約58% (macOS自体は全OSの約11%なので全体の約6%)
と、まだまだシェアは多少あり、無視はしにくい印象です。
Strict
として扱われてしまうと単なるGETでの遷移でもCookieが付かなくなり影響が大きいため、
完全でないですが、ある程度緩和が期待できるこういった施策を入れるのが良さそうです。
2020/02/06
ユーザーエージェント判定について
NoneがStrictになるブラウザのユーザーエージェント判定を含め、
Noneに互換性のないブラウザ(ユーザーエージェント)をざっくり和訳&まとめました。
判定方法など詳しくはSameSite=None: Known Incompatible Clientsをご覧ください。
またそのページにもある通り、完全なものではなく、しっかりと動作検証する必要があります。
( @sakai さん、情報ありがとうございます )
ブラウザ | 概要 |
---|---|
Chrome 51以上~66以下のブラウザ |
None を指定すると拒否する。Chromium由来の古いバージョンのブラウザーとAndroid WebViewも同様 これは当時Noneが仕様に無かったから。 なお51未満は無視されるので None と同じ動作になる。 |
AndroidのUC Browser 12.13.2未満 |
None を指定すると拒否する。こちらも当時 None が仕様に無かった。 |
macOS 10.14のSafariと組み込みブラウザ iOS 12のすべてのバージョンのブラウザ |
※2020/02/03の追記と同じ。 |
Secure属性を付けずにSameSite=Noneを指定した場合の動き
Secure属性を付けずにSameSite=Noneを指定した場合、set-cookie
ヘッダー自体が無効となります。
すなわちCookie自体を持つことができません。
Chrome 80 (flagsで設定変更した上で) で確認したところ、F12を押して出てくるDevToolsのNetworkのHeadersで見てみると、
set-cookie
の行末に⚠アイコンが表示されSameSite=NoneのときはSecureが必須である旨の警告が表示されます。
ほかSameSite未指定の場合のサードパーティCookie発行でも警告がでます。
またChrome 80ではDevToolsのNetworkに Only show requests with SameSite issues のチェックが追加されました。
ここにチェックを入れると、上記のような⚠アイコンのもののみにフィルタされます。
2020/02/09
SameSite無しのCookie発行後、2分間はPOSTでも送信できる点について
2020 年 2 月の SameSite Cookie の変更: 知っておくべきこと より、
2分間はPOST等でもCookieを送れる仕様について、
認証の過程でウェブサイトと認証の連携先(サードパーティプロバイダ)とでCookieを渡すときに
ログインに影響がないように配慮されたものとのことです。
2分である理由は書いていませんが、HTTPの接続タイムアウトが120秒であることが多いからでしょうか。
とはいえログイン時にユーザー識別Cookieを発行し
その場で外部と連携して2分以内に戻ってくる場合のみ有効で、
ログイン前からユーザーセッションをCookieで管理をしていたり、
3Dセキュアのように2分で戻るかわからない場合には無効です。
また将来的には廃止されるとのことなので、
現在この仕様でうまく動いていてもいずれ対応が必要になってきます。
Support for this intervention ("Lax + POST") will be removed in the future.
2020/04/07
4/3にSameSite Updatesに更新がありました。
COVID-19 (新型コロナウイルス) の影響により重要なサイトへのアクセスの安定性を確保するため、
SameSiteの動きを一時的に元に戻すようです。
再開は夏を目標としているとのことです。
2020/07/17
7/14にChrome 84がリリースされました。(SameSite Updates 7/14)
84だけでなく、80、81、83のStableにも数週間で段階的に適用されますので、
アップデートしなければ挙動が変わらないということではありません。
※なお82は欠番です。
2022/01/19
FirefoxでもSameSiteがデフォルトでlax
になりました。
バージョン96.0からになります。
Firefox リリースノート