Chrome、Firefox、Edge などは、IETF の提案である Incrementally Better Cookies に沿って、デフォルトの動作を変更しています。
SameSite
属性が設定されていない Cookie はSameSite=Lax
として扱われます。つまり、デフォルトの動作では、Cookie はファーストパーティ コンテキストにのみ制限されます。- cross-site で使用する Cookie は、サードパーティのコンテキストで含めることができるように
SameSite=None; Secure
を指定しなければなりません。
まだ対応していない場合は、サードパーティ Cookie の属性を更新して、今後ブロックされないようにする必要があります。
クロスサイト Cookie またはサードパーティ Cookie のユースケース
サードパーティ コンテキストで Cookie を送信する必要がある一般的なユースケースとパターンがいくつかあります。これらのユースケースのいずれかを提供している場合や、これらのユースケースに依存している場合は、サービスが正しく機能するように、ユーザーまたはプロバイダが Cookie を更新していることを確認してください。
<iframe>
内のコンテンツ
<iframe>
に表示される別のサイトのコンテンツは、サードパーティ コンテキストにあります。標準的なユースケースは次のとおりです。
- 他のサイトから共有された埋め込みコンテンツ(動画、地図、コードサンプル、ソーシャル投稿など)。
- 支払い、カレンダー、予約などの外部サービスのウィジェット。
- ソーシャル ボタンや不正防止サービスなどのウィジェットで、
<iframes>
が目立たないように作成されている。
Cookie は、セッションの状態の維持、一般的な設定の保存、統計情報の有効化、既存のアカウントを持つユーザー向けのコンテンツのパーソナライズなどの目的で使用されることがあります。

ウェブは本質的にコンポーザブルであるため、<iframes>
はトップレベルまたはファーストパーティ コンテキストで表示されるコンテンツを埋め込むためにも使用されます。iframe に表示されたサイトで使用されている Cookie は、すべてサードパーティ Cookie と見なされます。他のサイトに埋め込むサイトを作成していて、そのサイトを機能させるために Cookie が必要な場合は、それらの Cookie がクロスサイトで使用されるようにマークされているか、Cookie がなくても正常にフォールバックできることを確認する必要があります。
サイト間の「安全でない」リクエスト
「安全でない」という言葉は少し心配に聞こえるかもしれませんが、ここでは状態の変更を目的とする可能性のあるリクエストを指します。ウェブでは、主に POST リクエストです。SameSite=Lax
とマークされた Cookie は、別のサイトに移動するリンクをクリックするなど、安全なトップレベル ナビゲーションで送信されます。ただし、POST を使用して別のサイトに <form>
を送信する場合など、Cookie は含まれません。

このパターンは、ユーザーをリモート サービスにリダイレクトして何らかのオペレーションを実行してから戻るサイト(サードパーティの ID プロバイダにリダイレクトするなど)で使用されます。ユーザーがサイトを離れる前に、1 回限りのトークンを含む Cookie が設定されます。このトークンは、リクエストの戻り時にチェックされ、クロスサイト リクエスト フォージェリ(CSRF)攻撃を軽減することが期待されます。そのリクエストが POST で返される場合は、Cookie を SameSite=None; Secure
としてマークする必要があります。
リモート リソース
ページの <img>
タグや <script>
タグなどのリモート リソースは、リクエストとともに送信される Cookie に依存している可能性があります。一般的なユースケースには、トラッキング ピクセルやコンテンツのパーソナライズなどがあります。
これは、fetch
または XMLHttpRequest
を使用して JavaScript から送信されたリクエストにも適用されます。credentials: 'include'
オプションを指定して fetch()
が呼び出された場合、これらのリクエストには Cookie が含まれる可能性があります。XMLHttpRequest
の場合、通常、予想される Cookie は true
の withCredentials
値で示されます。これらの Cookie は、クロスサイト リクエストに含まれるように適切にマークする必要があります。
WebView 内のコンテンツ
プラットフォーム固有のアプリの WebView はブラウザによって動作します。デベロッパーは、アプリに影響する制限や問題がアプリの WebView にも適用されるかどうかをテストする必要があります。
Android では、プラットフォーム固有のアプリが CookieManager API を使用して Cookie を直接設定することもできます。ヘッダーまたは JavaScript を使用して設定された Cookie と同様に、クロスサイトで使用することを目的としている場合は、SameSite=None; Secure
を含めることを検討してください。
SameSite
を実装する方法
ファーストパーティ コンテキストでのみ必要な Cookie は、必要に応じて SameSite=Lax
または SameSite=Strict
としてマークします。これらの Cookie をマークせずに、デフォルトのブラウザの動作に依存して処理すると、ブラウザ間で動作に一貫性がなくなり、Cookie ごとにコンソール警告がトリガーされる可能性があります。
Set-Cookie: first_party_var=value; SameSite=Lax
サードパーティ コンテキストで必要な Cookie は SameSite=None; Secure
としてマークしてください。どちらの属性も必須です。Secure
を指定せずに None
のみを指定すると、Cookie は拒否されます。ブラウザの実装の違いを考慮して、互換性のないクライアントを処理するで説明されている軽減策の一部を使用する必要がある場合があります。
Set-Cookie: third_party_var=value; SameSite=None; Secure
互換性のないクライアントを処理する
None
を含める変更とデフォルトの動作の更新はまだ比較的新しいため、ブラウザによって処理方法が異なります。既知の問題のリストについては、chromium.org の更新ページをご覧ください。ただし、このリストがすべてを網羅しているとは限りません。
考えられる回避策の 1 つは、新しいスタイルと古いスタイルの両方で各 Cookie を設定することです。
Set-cookie: 3pcookie=value; SameSite=None; Secure
Set-cookie: 3pcookie-legacy=value; Secure
新しい動作を実装しているブラウザは、SameSite
値で Cookie を設定します。新しい動作を実装していないブラウザは、その値を無視して 3pcookie-legacy
Cookie を設定します。含まれている Cookie を処理する際、サイトはまず新しいスタイルの Cookie の有無を確認し、新しい Cookie が見つからない場合は以前の Cookie にフォールバックする必要があります。
次の例は、Express フレームワークとその cookie-parser ミドルウェアを使用して、Node.js でこれを行う方法を示しています。
const express = require('express');
const cp = require('cookie-parser');
const app = express();
app.use(cp());
app.get('/set', (req, res) => {
// Set the new style cookie
res.cookie('3pcookie', 'value', { sameSite: 'none', secure: true });
// And set the same value in the legacy cookie
res.cookie('3pcookie-legacy', 'value', { secure: true });
res.end();
});
app.get('/', (req, res) => {
let cookieVal = null;
if (req.cookies['3pcookie']) {
// check the new style cookie first
cookieVal = req.cookies['3pcookie'];
} else if (req.cookies['3pcookie-legacy']) {
// otherwise fall back to the legacy cookie
cookieVal = req.cookies['3pcookie-legacy'];
}
res.end();
});
app.listen(process.env.PORT);
このアプローチでは、冗長な Cookie を設定し、Cookie の設定と読み取りの両方の時点で変更を行うという追加の作業が必要になります。ただし、ブラウザの動作に関係なくすべてのブラウザを対象とし、サードパーティ Cookie の機能を維持する必要があります。
別の方法として、Set-Cookie
ヘッダーが送信されたときに、ユーザー エージェント文字列を使用してクライアントを検出することもできます。互換性のないクライアントのリストを参照し、プラットフォームに適したユーザー エージェント検出ライブラリ(Node.js の ua-parser-js ライブラリなど)を使用します。このアプローチでは 1 回の変更のみで済みますが、ユーザー エージェント スニッフィングでは影響を受けるすべてのユーザーを検出できない可能性があります。
言語、ライブラリ、フレームワークでの SameSite=None
のサポート
ほとんどの言語とライブラリは、Cookie の SameSite
属性をサポートしています。ただし、SameSite=None
の追加はまだ比較的最近であるため、当面は標準の動作を回避する必要があるかもしれません。これらの動作については、GitHub の SameSite
サンプル リポジトリで説明しています。
困ったときは
Cookie はウェブのあらゆる場所で使用されており、特にクロスサイトのユースケースでは、サイトが Cookie を設定して使用している場所を開発チームが完全に把握していることはほとんどありません。問題が発生した場合は、それが初めてのケースである可能性もあります。遠慮なくお問い合わせください。
- GitHub の
SameSite
サンプル リポジトリで問題を報告します。 - StackOverflow の「samesite」タグで質問します。
- Chromium の動作に関する問題については、Chromium Issue Tracker でバグを報告してください。
- Chrome の進捗状況については、
SameSite
更新ページをご覧ください。