すべての Cookie には、Cookie の使用場所と使用タイミングを制御する多くの属性とともに、Key-Value ペアが含まれています。
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 の使用を宣言する
クッキーの 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 のないデフォルトの動作の変更
対応ブラウザ
SameSite
属性は広くサポートされていますが、広く採用されていません。以前は、SameSite
なしで Cookie を設定すると、デフォルトですべてのコンテキストで Cookie が送信されていました。これにより、ユーザーは CSRF や意図しない情報漏洩の危険にさらされていました。デベロッパーが意図を表明し、ユーザーに安全なエクスペリエンスを提供できるように、IETF の提案である Incrementally Better Cookies では、次の 2 つの重要な変更が提案されています。
SameSite
属性が設定されていない Cookie はSameSite=Lax
として扱われます。SameSite=None
の Cookie には、Secure
も指定する必要があります。つまり、そうした Cookie はセキュア コンテキストを必要とします。
これらの変更はどちらも、以前のバージョンの SameSite
属性を正しく実装したブラウザと、以前の SameSite
バージョンをサポートしていないブラウザとの下位互換性があります。Cookie の動作と想定される用途を明示することで、デベロッパーがブラウザのデフォルトの動作に依存することを減らすことを目的としています。SameSite=None
を認識しないクライアントは、それを無視する必要があります。
デフォルトは SameSite=Lax
SameSite
属性を指定せずに Cookie を送信すると、ブラウザは Cookie を SameSite=Lax
に設定されているものとして扱います。ブラウザ間でユーザー エクスペリエンスの整合性を高めるため、SameSite=Lax
を明示的に設定することをおすすめします。
SameSite=None
は安全である必要があります
SameSite=None
を使用してクロスサイト Cookie を作成する場合は、ブラウザが 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
クッキーのレシピ
SameSite=None
の変更とブラウザの動作の違いを適切に処理するために Cookie を更新する方法について詳しくは、フォローアップ記事の SameSite Cookie のレシピをご覧ください。
Lily Chen、Malte Ubl、Mike West、Rob Dodson、Tom Steiner、Vivek Sekhar からのご協力とフィードバックに感謝します。
Cookie のヒーロー画像: Unsplash の Pille-Riin Priske