2020年2月4日に Chrome 80 がリリースされました。 このバージョンでは既存のWebアプリケーションの振る舞いに大きな影響を与える変更として、クッキーのSameSite属性の既定値が変わるというのがあります。
ただし、振る舞いの変更は、2月18日以降に予定されています。(正確には「2月17日の週でアメリカ合衆国大統領の日を除く」)
Enforcement rollout for Chrome 80 Stable: 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, excluding the US President’s Day holiday on Monday. We will be closely monitoring and evaluating ecosystem impact from this initial limited phase through gradually increasing rollouts. SameSite Updates - The Chromium Projects
この仕様変更についてはChrome 80が密かに呼び寄せる地獄 ~ SameSite属性のデフォルト変更を調べてみた - Qiitaが詳しいので、この記事では説明しません。 しかし、概要を把握した上で、以下を読んでおくことをお勧めします。
- Google Developers Japan: 新しい Cookie 設定 SameSite=None; Secure の準備を始めましょう
- 対応するにあたっては「準備方法と既知の複雑なケース」を読み飛ばさないほうがよいです。
1) 2分間は、SameSite=Lax のクッキーがPOST時に送信される仕様
Chrome 80 以降の振る舞いをテストするには、chrome://flags
で以下の項目をEnabledにする必要があります。
- SameSite by default cookies
- Cookies without SameSite must be secure
さらに、仕様変更の影響を緩和させる措置として、SameSite=Lax のクッキーはトップレベルのクロスドメインPOST 時に発行から2分間は送信されるChromeの仕様に注意が必要です。(最終リクエストから2分間ではなく、クッキー発行から2分間)
トップレベルのクロスドメインリクエストとは、iframe 内のPOSTやXHRではない、通常のフォームでの画面遷移を伴うPOSTのことです。
つまり既存のアプリケーションの振る舞いに影響しないかをChromeを使って調査するときは、クッキー発行後2分待つ必要があるということです。
この一時的な介入は将来的に削除される予定ですが、アプリケーションの検証時には、無効化したいこともあると思います。その場合、以下のようにChrome起動時にオプションを指定して無効化できます。(macOSの場合) (Chrome 79では使えなかったのでChrome Canaryを使う必要がありましたが、Chrome 80では使えるようになっています。(おそらく80 Beta版でも使えたのではないでしょうか))
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --enable-features=SameSiteDefaultChecksMethodRigorously
Starting in Canary version 80.0.3975.0, the Lax+POST temporary mitigation can be disabled for testing purposes using the new flag --enable-features=SameSiteDefaultChecksMethodRigorously to allow testing of sites and services in the eventual end state of the feature where the mitigation has been removed.
2) SameSite=None が一部の古いブラウザで機能しない問題
SameSite=Lax
だと動作しなくなる場合、SameSite=None; Secure
に変更することで振る舞いを維持する、という解決策があります。(SameSite=None; Secure
を送出する場合、CSRFのリスクを考慮する必要があります。)
Google Developers Japan: 新しい Cookie 設定 SameSite=None; Secure の準備を始めましょうに
特定のバージョンの Chrome、Safari、UC Browser など、一部のブラウザは None 値を意図しない方法で処理する可能性があります。その場合、デベロッパーはそのようなクライアント向けに例外処理をコーディングする必要があります。これには、古いバージョンの Chrome が提供している Android の WebView も含まれます。既知の互換性のないクライアントの一覧はこちらです。
と書かれていて、SameSite=None
のクッキーを削除したり、SameSite=Strict
とするブラウザがあるようです。そのようなブラウザを判定するためのコードがSameSite=None: Known Incompatible Clients - The Chromium Projectsで紹介されています。それによれば
- Chrome 51〜66
- Android版UC Browser バージョン12.13.2以前
- MacOS 10.14 のSafari とSafari組み込みブラウザ、iOS 12のすべてのブラウザ
に問題があるとのことです。macOS 10.14 と iOS 12 の影響が大きそうです。
まとめ
最初にSameSiteの話を詳しく調査したとき、2分間はSameSite=Lax+POSTでクッキー送信されるというのを見逃していて後日知って焦りました。共有するために記事を書きました。
CSRF対策として既定がSameSite=Laxに変わることは歓迎しますが、既存アプリをサポートする立場だと注意点がありますね。