すべての Cookie には、Key-Value ペアと、Cookie をいつ、どこで使用するかを制御するいくつかの属性が含まれています。
SameSite
属性(RFC6265bis で定義)を導入すると、Cookie をファーストパーティ コンテキストと同一サイト コンテキストのどちらに制限するかを宣言できます。ここでの「サイト」の意味を正確に理解しておくと役に立ちます。
サイトとは、ドメイン サフィックスとその直前のドメイン部分を組み合わせたものです。たとえば、www.web.dev
ドメインは web.dev
サイトの一部です。
重要な用語: ユーザーが www.web.dev
を使用していて、static.web.dev
から画像をリクエストする場合、それは同じサイト リクエストです。
公開サフィックス リストでは、同じサイト内にあるとみなすページを定義します。.com
などのトップレベル ドメインに依存するだけでなく、github.io
などのサービスを含めることもできます。これにより、your-project.github.io
と my-project.github.io
を別々のサイトとしてカウントできるようになります。
重要な用語: ユーザーが your-project.github.io
を使用していて、my-project.github.io
から画像をリクエストすると、これはクロスサイト リクエストです。
SameSite
属性を使用して Cookie の使用を宣言する
Cookie の SameSite
属性には、この動作を制御する 3 つの方法が用意されています。属性を指定しないか、Strict
または Lax
を使用して Cookie を同一サイトのリクエストに制限できます。
SameSite
を Strict
に設定した場合、Cookie はファーストパーティ コンテキストでのみ送信できます。つまり、Cookie のサイトがブラウザのアドレスバーに表示されているサイトと一致している必要があります。たとえば、promo_shown
Cookie が次のように設定されているとします。
Set-Cookie: promo_shown=1; SameSite=Strict
ユーザーがサイトにアクセスすると、リクエストとともに Cookie が想定どおりに送信されます。
ただし、ユーザーが別のリンクからサイトにアクセスした場合、その最初のリクエストで Cookie は送信されません。これは、パスワードの変更や購入など、常に最初のナビゲーションを必要とする機能に関連する Cookie に適していますが、promo_shown
のような Cookie にとっては制限が強すぎます。読者がリンクをクリックしてサイトにアクセスすると、設定を適用できるように Cookie が送信されます。
SameSite=Lax
を使用すると、ブラウザからこれらのトップレベル ナビゲーションとともに Cookie を送信できるようになります。たとえば、別のサイトがサイトのコンテンツを参照している場合は、猫の写真を使用して次のように記事へのリンクを提供します。
<p>Look at this amazing cat!</p>
<img src="https://blog.example/blog/img/amazing-cat.png" />
<p>Read the <a href="https://blog.example/blog/cat.html">article</a>.</p>
Cookie が次のように Lax
に設定されているとします。
Set-Cookie: promo_shown=1; SameSite=Lax
ブラウザが他のユーザーのブログに対する amazing-cat.png
をリクエストしても、サイトから Cookie は送信されません。ただし、読者がサイト上の cat.html
へのリンクをたどる場合、そのリクエストに Cookie が含まれます。
このように SameSite
を使用し、ウェブサイトの表示に影響する Cookie を Lax
に、ユーザー操作に関連する Cookie を Strict
に設定することをおすすめします。
また、SameSite
を None
に設定して、すべてのコンテキストで Cookie を送信することを示すこともできます。ウィジェット、埋め込みコンテンツ、アフィリエイト プログラム、広告、ログインなど、他のサイトが利用するサービスを提供する場合は、None
を使用して意図を明確にします。
SameSite を使用しない場合のデフォルトの動作の変更
対応ブラウザ
- 80
- 86
- x
SameSite
属性は広くサポートされていますが、広く採用されていません。以前は、SameSite
なしで Cookie を設定すると、デフォルトですべてのコンテキストで Cookie が送信されるため、ユーザーは CSRF や意図しない情報漏洩に対して脆弱なままになります。デベロッパーが自身の意図を表明し、より安全なエクスペリエンスを提供できるように、IETF の提案である Incrementally Better Cookie では、次の 2 つの重要な変更点が示されています。
SameSite
属性が設定されていない Cookie はSameSite=Lax
として扱われます。SameSite=None
を使用する Cookie では、Secure
も指定する必要があります。つまり、安全なコンテキストが必要です。
どちらの変更も、以前のバージョンの SameSite
属性を正しく実装しているブラウザや、以前のバージョンの SameSite
をサポートしていないブラウザとの下位互換性があります。Cookie の動作と使用目的を明確にすることで、デベロッパーがブラウザのデフォルトの動作に依存しないようにすることを目的としています。SameSite=None
を認識しないクライアントは無視する必要があります。
デフォルトは SameSite=Lax
SameSite
属性を指定せずに Cookie を送信した場合、ブラウザは SameSite=Lax
に設定されているかのようにその Cookie を扱います。それでも、SameSite=Lax
を明示的に設定して、ブラウザ間でユーザー エクスペリエンスの一貫性を高めることをおすすめします。
SameSite=None
は安全である必要があります
SameSite=None
を使用してクロスサイト Cookie を作成する場合は、ブラウザで受け入れられるように、Secure
に設定する必要もあります。
Set-Cookie: widget_session=abc123; SameSite=None; Secure
この動作をテストするには、Chrome 76 以降では about://flags/#cookies-without-same-site-must-be-secure
を有効にし、Firefox 69 以降では about:config
で network.cookie.sameSite.noneRequiresSecure
を設定します。
また、既存の Cookie をできるだけ早く Secure
に更新することをおすすめします。
サイトで第三者のコンテンツを提供するサービスを利用している場合は、サービス プロバイダが Cookie を更新していることを確認し、サイトのスニペットや依存関係を更新して、新しい動作を使用するようにしてください。
SameSite
のクッキーのレシピ
Cookie を更新して SameSite=None
への変更を適切に処理する方法と、ブラウザの動作の違いについて詳しくは、関連記事 SameSite Cookie の使い方をご覧ください。
Lily Chen、Malte Ubl、Mike West、Rob Dodson、Tom Steiner、Vivek Sekhar の協力とフィードバックに感謝します。
Cookie のヒーロー画像(作成者: Pille-Riin Priske、Unsplash)