Skip to content
概要 ブログ 学習する 探検 パターン Case studies
このページ内
  • クロスブラウザのサポート
  • クロスサイトまたはサードパーティCookieの使用例
    • <iframe>内のコンテンツ
    • サイト間での「安全でない」要求
    • リモートリソース
    • WebView内のコンテンツ
  • SameSiteを実装する方法
    • 互換性がないクライアントの取り扱い
  • 言語、ライブラリ、フレームワークでのSameSite=Noneのサポート
  • ヘルプ
  • Home
  • All articles

SameSite Cookieレシピ

今後のSameSite属性の動作の変更に備えて、サイトのCookieを更新します。

Oct 30, 2019 — 更新済み May 28, 2020
Available in: English、Español、Português、Русский、中文、한국어
Appears in: 安全とセキュリティ
Rowan Merewood
Rowan Merewood
TwitterGitHubGlitch
このページ内
  • クロスブラウザのサポート
  • クロスサイトまたはサードパーティCookieの使用例
    • <iframe>内のコンテンツ
    • サイト間での「安全でない」要求
    • リモートリソース
    • WebView内のコンテンツ
  • SameSiteを実装する方法
    • 互換性がないクライアントの取り扱い
  • 言語、ライブラリ、フレームワークでのSameSite=Noneのサポート
  • ヘルプ
この記事は、Cookie の SameSite 属性の変更を扱うシリーズ記事の一部です。 - SameSite Cookie の説明 - SameSite Cookie のレシピ - スキームフル Same-Site

Chrome、Firefox、Edgeなどは、IETFの提案であるIncrementally Better Cookiesに沿って、デフォルトの動作を次のように変更します。

  • SameSite属性のないCookieはSameSite=Laxとして扱われます。つまり、デフォルトの動作では、Cookieはファーストパーティのコンテキストのみに制限されます。
  • クロスサイト使用のCookieは、SameSite=None; Secureを指定し、サードパーティコンテキストを追加できるようにする必要があります。

この機能は、 Chrome 84 stable以降のデフォルトの動作です。まだ対応していない場合は、サードパーティのCookieの属性を更新して、将来ブロックされないようにしてください。

クロスブラウザのサポート #

MDNのSet-Cookieページのブラウザの互換性セクションを参照してください。

クロスサイトまたはサードパーティCookieの使用例 #

さまざまな一般的なユースケースやパターンでは、Cookieをサードパーティのコンテキストで送信する必要があります。これらのユースケースのいずれかを提供したり、依存したりしている場合は、確実にサービスが正しく機能し続けるように、ユーザーまたはプロバイダのいずれかがCookieを更新していることを確認してください。

<iframe>内のコンテンツ #

<iframe>で表示される別のサイトのコンテンツは、サードパーティのコンテキストにあります。ここでの標準的な使用例は次のとおりです。

  • 動画、地図、コードサンプル、ソーシャル投稿など、他のサイトから共有される埋め込みコンテンツ。
  • 決済、カレンダー、手配、予約機能などの外部サービスのウィジェット。
  • あまり明確ではない<iframes>を作成するソーシャルボタンや不正防止サービスなどのウィジェット。

ここでは、Cookieを使用して、セッションの状態を維持したり、一般的な設定を保存したり、統計を有効にしたり、既存のアカウントを持つユーザーのコンテンツをパーソナライズしたりできます。

埋め込みコンテンツのURLがページのURLと一致しないブラウザウィンドウの図。
埋め込まれたコンテンツが最上位のブラウジングコンテキストと同じサイトから取得されていない場合は、サードパーティのコンテンツです。

さらに、本質的に、Webは構成可能であるため、<iframes>は、最上位またはファーストパーティのコンテキストでも表示されるコンテンツを埋め込むために使用されます。そのサイトで使用されているすべてのCookieは、サイトがフレーム内に表示されたときにサードパーティのCookieと見なされます。他のユーザーが簡単に埋め込むことができるサイトを作成し、Cookieを機能させる場合は、確実にサイト間で使用できるように設定するか、Cookieを使用せずにフォールバックできるようにする必要があります。

サイト間での「安全でない」要求 #

「安全ではない」と言うと少し不安に思われるかもしれませんが、これは状態を変更することを目的とした要求を指します。Webでは、これは主にPOST要求です。SameSite=Laxに設定されたCookieは、安全な最上位のナビゲーションで送信されます。たとえば、リンクをクリックして別のサイトに移動します。ただし、POST経由の別のサイトへの<form>送信などには、Cookieは含まれません。

あるページから別のページに送信される要求の図。
受信要求が「安全な」方法を使用している場合、Cookieが送信されます。

このパターンは、ユーザーをリモートサービスにリダイレクトして、戻る前に何らかの操作を実行する可能性のあるサイトに使用されます。たとえば、サードパーティのIDプロバイダーにリダイレクトします。ユーザーがサイトを離れる前に、クロスサイトリクエストフォージェリ (CSRF) 攻撃を軽減するために、返される要求でこのトークンをチェックできるように、使い捨てトークンを含むCookieが設定されます。その返り要求がPOST経由で送信される場合、CookieをSameSite=None; Secureに設定する必要があります。

リモートリソース #

ページのリモートリソースは、<img>タグ、 <script>タグなどから要求ともに送信されるCookieに依存している可能性があります。一般的な使用例には、ピクセルの追跡とコンテンツのパーソナライズが含まれます。

これは、fetchまたはXMLHttpRequestによってJavaScriptから開始された要求にも当てはまります。fetch()がcredentials: 'include'オプションを使用して呼び出された場合、これらの要求でCookieが想定される可能性があることを示します。XMLHttpRequestの場合、trueに設定されているwithCredentialsプロパティのインスタンスを探します。これは、これらのリクエストでCookieが想定される可能性があることを示します。これらのCookieは、クロスサイト要求に含めるように適切に設定する必要があります。

WebView内のコンテンツ #

プラットフォーム固有のアプリのWebViewはブラウザに基づいているため、同じ制限や問題が当てはまるかどうかをテストする必要があります。Androidでは、WebViewがChromeに基づく場合、新しいデフォルト値はすぐにChrome 84に適用されません。ただし、今後は適用される予定です。このため、この点についてまだテストして準備してください。また、Androidでは、直接CookieManager APIを使用して、プラットフォーム固有のアプリでCookieを設定できます。 ヘッダーまたはJavaScriptで設定されたCookieのように、クロスサイトで使用する計画の場合は、SameSite=None; Secureを追加することを検討してください。

SameSiteを実装する方法 #

ファーストパーティのコンテキストでのみ必要なCookieの場合、必要に応じて、SameSite=LaxまたはSameSite=Strictに設定することをお勧めします。何もせずにブラウザのデフォルトを適用させることもできますが、ブラウザ間で一貫性のない動作が発生し、各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の更新ページを参照できますが、これが網羅的であるかどうかを判断することはできません。これは理想的ではありませんが、この移行フェーズで採用できる回避策があります。ただし、一般的なルールは、互換性のないクライアントを特別な場合として扱うことです。新しいルールを実装しているブラウザの例外を作成しないでください。

Noneを含み、デフォルトの動作を更新するこれらの変更はまだ比較的新しいため、これらの変更の処理方法に関してブラウザ間で一貫性がありません。現在確認済みの問題については、chromium.orgの更新ページを参照できますが、これが網羅的であるかどうかを判断することはできません。これは理想的ではありませんが、この移行フェーズで採用できる回避策があります。ただし、一般的なルールは、互換性のないクライアントを特別な場合として扱うことです。新しいルールを実装しているブラウザの例外を作成しないでください。

Set-cookie: 3pcookie=value; SameSite=None; Secure
Set-cookie: 3pcookie-legacy=value; Secure

新しい動作を実装するブラウザはSameSite値でCookieを設定しますが、他のブラウザではそれが無視されるか、誤って設定される可能性があります。ただし、これらの同じブラウザでは、3pcookie-legacy Cookieが設定されます。含まれているCookieを処理するときには、サイトは最初に新しいスタイルのCookieの存在を確認し、見つからない場合はレガシーCookieにフォールバックします。

以下の例は、Node.jsでこの処理を行う方法を示しています。Expressフレームワークとそのcookie-parserミドルウェアを使用しています。

const express = require('express');
const cp = require('cookie-parser');
const app = express();
app.use(cp());

app.get('/set', (req, res) => {
// 新しいスタイルCookieを設定
res.cookie('3pcookie', 'value', { sameSite: 'none', secure: true });
// レガシーCookieで同じ値を設定
res.cookie('3pcookie-legacy', 'value', { secure: true });
res.end();
});

app.get('/', (req, res) => {
let cookieVal = null;

if (req.cookies['3pcookie']) {
// 最初に新しいスタイルCookieを確認
cookieVal = req.cookies['3pcookie'];
} else if (req.cookies['3pcookie-legacy']) {
// ない場合はレガシーCookieにフォールバック
cookieVal = req.cookies['3pcookie-legacy'];
}

res.end();
});

app.listen(process.env.PORT);

この方法の欠点は、すべてのブラウザに対応するように冗長Cookieを設定しなければならず、Cookieの設定と読み取りの両方の時点で変更する必要があることです。ただし、この方法では、動作に関係なくすべてのブラウザに対応し、サードパーティCookieが以前と同じように機能し続けることが保証されます。

別の方法として、Set-Cookieヘッダーを送信する時点で、ユーザーエージェント文字列経由でクライアントを検出するように選択することもできます。互換性のないクライアントのリストを参照してから、プラットフォームに適したライブラリ (Node.jsのua-parser-jsライブラリなど) を利用してください。これらの正規表現を自分で記述せずに済むように、ユーザーエージェントの検出を処理するライブラリを見つけることをお勧めします。

この方法の利点は、Cookieを設定する時点で1つの変更を加えるだけで済むことです。ただし、ユーザーエージェントのスニッフィングは本質的に脆弱であり、影響を受けるすべてのユーザーを特定できない可能性があるため、注意が必要です。

選択するオプションに関係なく、レガシールートで送信されるトラフィックのレベルをログに記録する方法があることを確認することをお勧めします。これらのレベルがサイトの許容しきい値を下回ったら、この回避策を削除するように通知するリマインダまたはアラートがあることを確認してください。

言語、ライブラリ、フレームワークでのSameSite=Noneのサポート #

大半の言語とライブラリでCookieのSameSite属性がサポートされていますが、SameSite=Noneの追加はまだ比較的新しいため、今のところ標準的な動作の一部を回避する必要があるかもしれません。これらについては、GitHubのSameSiteサンプルリポジトリを参照してください。

ヘルプ #

Cookieはいたるところにあり、特にサイト間のユースケースを組み合わせて使用する場合は、Cookieが設定され、使用されている場所がサイトによって完全に監査されていることはめったにありません。問題が発生した場合、初めてその問題が生じた可能性があります。その場合は、遠慮なく次の方法でお問い合わせください。

  • GitHubのSameSiteサンプルリポジトリで問題を登録する。
  • StackOverflowで「samesite」タグに関する質問をブログに投稿する。
  • Chromiumの動作に関する問題については、 [SameSitecookies]問題テンプレートをでバグを登録する。
  • SameSite更新ページでChromeの進捗状況をフォローする。

Cookieヒーロー画像の提供: Unsplash の Pille-Riin Priske

セキュリティCookiesChrome 80
最終更新: May 28, 2020 — 記事を改善する
Return to all articles
共有する
サブスクライブする

Contribute

  • バグを報告する
  • ソースを表示する

関連性のあるコンテンツ

  • developer.chrome.com
  • Chrome のアップデート
  • ケーススタディ
  • ポッドキャスト
  • ショー

接続する

  • Twitter
  • YouTube
  • Google Developers
  • Chrome
  • Firebase
  • Google Cloud Platform
  • すべての製品
  • 利用規約とプライバシーポリシー
  • コミュニティガイドライン

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies.