• 診断項目 No.38/127
  • Cookie・セッション管理
  • 重大度 重要(high)

SameSite=NoneとSecureの組み合わせとは?Secureなしで拒否される理由・設定方法・診断基準

SameSite=NoneとSecureの組み合わせは、クロスサイト用Cookieの必須条件です。Secureが無いとブラウザがCookieを保存せず外部連携が止まる理由、rfc6265bisの規定、PHP・Apache・nginx・IIS等の設定例と診断基準を解説します。

結論(SameSite=NoneとSecureの組み合わせ)

SameSite=NoneとSecureの組み合わせとは、別サイトからのリクエストにも送られるSameSite=NoneのCookieに、HTTPSでのみ送信させるSecure属性を必ず併せて付けることです。改訂版Cookie仕様(rfc6265bis)は、Secureの無いSameSite=NoneのCookieを無視するよう定めており、主要ブラウザはそのCookieを保存しません。付け忘れはセキュリティ上の不備であると同時に、予約ウィジェットやSSOなどの連携機能が動かない原因にもなります。

この記事のポイント

  • SameSite=Noneは最も広く送信される値なので、少なくとも通信経路の暗号化(Secure)が必須とされています。
  • rfc6265bisの保存手順では、SameSite=NoneでSecureが無いCookieは処理を中止して完全に無視されます。
  • Chrome 80(2020年)から、Secureの無いSameSite=Noneは拒否されるようになりました。
  • 診断ではSameSite=NoneのCookieが1件でもSecureなしなら×(重み3)、SameSite=Noneが無ければ対象外です。
  • まずクロスサイト送信が本当に必要かを見直し、不要ならLaxへ変更するのが最善です。
診断項目名SameSite=NoneとSecureの組み合わせ
項目IDcookie.none-secure
分類Cookie・セッション管理
重大度・配点の重み重要(high) 重み 3
関連する標準・ガイドラインdraft-ietf-httpbis-rfc6265bis 5.7(Cookie保存手順:SameSite=None は secure-only-flag 必須)/OWASP ASVS 5.0.0 V3.3.1(Secure属性)・V3.3.2(SameSite属性)/OWASP WSTG-SESS-02/CWE-614(Sensitive Cookie in HTTPS Session Without 'Secure' Attribute)

SameSite=NoneとSecureの組み合わせとは

SameSite=NoneとSecureの組み合わせとは、SameSite=None を指定したCookieに、必ず Secure 属性も付けること です。セキュリティAIチェッカーは、この組み合わせが守られているかを確認します。

Set-Cookie: widget_sid=…; Path=/; SameSite=None; Secure

SameSite=None は「別サイトからのリクエストにもこのCookieを送ってよい」という最も緩い設定です。別サイトに埋め込まれた予約フォーム、シングルサインオン(SSO)、決済代行からの戻りなど、サイトをまたぐ連携に必要な場面で使われます。最も広く送信される値であるため、少なくとも通信経路は暗号化されていなければならない、という考え方から、ブラウザは SameSite=None に Secure を必須としています。

改訂版Cookie仕様(rfc6265bis)は、Cookieの保存手順の中で「same-site-flagが None のときは、secure-only-flag が true でない限り処理を中止し、Cookieを完全に無視する」と定めています。web.devの解説も「SameSite=Noneでクロスサイト用のCookieを作るときは、必ずSecureも設定しなければならない」と明記しています。つまり SameSite=None だけのCookieは、現在の主要ブラウザでは 保存されず、連携機能がそもそも動かない 状態です。セキュリティ上の不備であると同時に、機能不全の兆候でもあります。

SameSite=NoneにSecureが必須になった経緯と仕組み

ブラウザの動作の変遷

  • 以前のブラウザは、SameSite を指定しないCookieをすべてのリクエストに送っていました。
  • Chrome 80(2020年)から、SameSite 未指定のCookieは Lax 扱いとなり、クロスサイト送信が必要なCookieは明示的に SameSite=None; Secure とすることが求められるようになりました。このとき同時に、Secure の無い SameSite=None は拒否されるようになりました。
  • 一部の古いブラウザは SameSite=None を正しく解釈できない問題がありました(web.devも古いバージョンでの非互換に言及しています)。現在の主要ブラウザでは解消されています。

Secure属性との関係

Secure 付きCookieは、HTTPSの接続でしか設定・送信できません(rfc6265bisでは、安全でない接続から Secure 付きCookieを設定しようとしても無視されます)。したがって SameSite=None を使う機能は、サイト全体がHTTPSで動作していることが前提です。Secure属性そのものの解説は「CookieのSecure属性」、Strict・Lax・Noneの選び方は「CookieのSameSite属性」を参照してください。このページは「Noneを使うときのSecure必須要件」に集中しています。

Partitioned属性(CHIPS)との関係

サードパーティCookieの制限が進む中、埋め込みウィジェット用のCookieには Partitioned 属性(CHIPS)を組み合わせることがあります。Partitioned も Secure が必須で、通常は SameSite=None; Secure; Partitioned の形で使われます。Partitioned の要件は「Partitioned Cookieの要件」で評価します。

自治体サイトでSameSite=Noneが現れる典型例

  • ロードバランサーのクロスサイト用Cookie:クラウドのロードバランサーは、スティッキーセッション用Cookieをクロスサイトのリクエストでも維持するため、SameSite=None; Secure 付きの別名Cookieを発行することがあります。通常はSecureが付いており、この項目は○になります。
  • 外部埋め込みウィジェット:他団体のサイトや観光ポータルに埋め込まれる予約カレンダー、チャットボットなど。
  • SSO・外部認証連携:マイナンバーカードを用いた認証基盤や外部IdPから、POSTで戻ってくる画面のセッション維持。
  • 独自開発・古いフレームワーク:「とりあえず全CookieをSameSite=Noneにした」という設定が残っている場合。必要性を見直す対象です。

SameSite=NoneとSecureについてよくある誤解

  • 「SameSite=Noneを付ければ外部連携が動く」:Secure が無ければCookie自体が保存されません。
  • 「ブラウザが拒否するなら実害はない」:ブラウザの実装は一様ではなく、古い端末や組み込みブラウザ、アプリ内ブラウザでは受け入れられて平文で送信される可能性があります。また、連携機能の不具合として問い合わせ対応や回避策(Cookieを使わない独自実装)を誘発します。
  • 「SameSite=Noneを使っていなければこの項目は合格」:使っていなければ評価の対象がありません。セキュリティAIチェッカーでは対象外(na)として扱い、得点を加算も減点もしません。

SameSite=NoneとSecureの組み合わせの診断基準(セキュリティAIチェッカー)

取得方法

  1. トップページ(転送後の最終応答)と、トップページ内の同一オリジンリンクから選んだ最大4ページ(ログイン・管理・マイページ系を優先)を GETのみ で取得します。
  2. 各最終応答の Set-Cookie を1件ずつ収集します(転送途中の応答のCookieは観測しません)。
  3. 削除用のSet-Cookie(Max-Age=0 以下、または過去の Expires)は除外します。
  4. 残ったCookieのうち、SameSite=None(大文字小文字・= 前後の空白を区別しない、値が正確に None のもの)を抽出します。

判定条件

判定条件得点への影響
○ 問題なし(pass)SameSite=None のCookieが1件以上あり、そのすべてに Secure 属性がある重み3 × 1.00
× 要改善(fail)SameSite=None で Secure 属性の無いCookieが1件以上ある重み3 × 0
対象外(na)有効なCookieが無い(結果には重大度high・重み3のまま記録)、または SameSite=None のCookieが無い得点計算から除外
△ 要確認(warn)使用しません―
  • Secure の検出は「; の後に属性名 Secure があり、直後が ;・=・行末のいずれか」という条件で行います。
  • 根拠欄には、○のときは対象件数、×のときは「主要ブラウザは保存を拒否します」と表示します。

自治体サイトでの判定例

観測したSet-Cookie判定
AWSALBCORS=…; Path=/; SameSite=None; Secure○
widget_sid=…; Path=/; SameSite=None(Secureなし)×
PHPSESSID=…; path=/; secure; HttpOnly; SameSite=Lax のみ対象外(Noneが無いため)
Cookieの発行なし対象外

SameSite=NoneでSecureがないとどんなリスクがあるか

  • 連携機能の停止:外部の電子申請・予約・決済・SSOとの連携で、戻ってきたときにセッションが見つからず、手続きが途中で失敗します。原因が分かりにくく、住民からの問い合わせにつながります。
  • 平文送信による漏えい:Secure を受け付けない古いクライアントでは、このCookieが http:// のリクエストにも付与され、経路上で盗聴される可能性があります(CWE-614)。SameSite=None のCookieはクロスサイトのリクエストにも送られるため、送信機会が多いことも問題です。
  • 誤った回避策の誘発:Cookieが動かないことへの対処として、セッションIDをURLパラメータに載せるなどの危険な実装に切り替えられることがあります。IPA「安全なウェブサイトの作り方」4-(ii)は、セッションIDをURLパラメータに格納しないよう求めています(「セッションIDをURLへ含めていない」で確認します)。

SameSite=NoneとSecureの設定方法(PHP・Apache・nginx・IIS・Next.js)

基本方針

  1. そのCookieが本当にクロスサイトで送られる必要があるかを確認します。不要なら SameSite=Lax に変更するのが最善です。
  2. 必要なら SameSite=None; Secure とし、サイト全体をHTTPSで配信します。
  3. 埋め込み用途なら Partitioned の併用も検討します。

PHP(7.3以降)

<?php
setcookie('widget_sid', $id, [
    'path'     => '/',
    'secure'   => true,      // SameSite=None には必須
    'httponly' => true,
    'samesite' => 'None',
]);

Apache(補助策:SameSite=NoneでSecureの無いCookieに追加)

<IfModule mod_headers.c>
  Header always edit Set-Cookie "(?i)^(?=.*;\s*samesite\s*=\s*none\s*(?:;|$))(?!.*;\s*secure\s*(?:[;=]|$))(.*)$" "$1; Secure"
  Header edit Set-Cookie "(?i)^(?=.*;\s*samesite\s*=\s*none\s*(?:;|$))(?!.*;\s*secure\s*(?:[;=]|$))(.*)$" "$1; Secure"
</IfModule>

Apacheは応答ヘッダーを2つの内部表で管理しており、CGI・FastCGI(mod_proxy_fcgi)由来の Set-Cookie は always 側、それ以外の多くは既定(onsuccess)側に入るため、両方の条件で記述します。

nginx(リバースプロキシ)

# 特定のCookieにだけ付与(nginx 1.19.3以降)
proxy_cookie_flags widget_sid secure samesite=none;

IIS(ASP.NET 4.7.2以降)

<system.web>
  <httpCookies requireSSL="true" />
  <sessionState cookieSameSite="None" />
</system.web>

cookieSameSite="None" は外部連携が必要な場合に限り使い、requireSSL="true" と必ず組み合わせます。

Next.js(Vercel)

import { cookies } from "next/headers";

(await cookies()).set("widget_sid", id, { sameSite: "none", secure: true, httpOnly: true, path: "/" });

確認方法と注意点

curl -sSI https://www.city.example.lg.jp/ | grep -i '^set-cookie' | grep -i 'samesite=none'
  • 出力された各行に Secure が含まれることを確認します。
  • ブラウザの開発者ツール(Application → Cookies)で、該当Cookieが保存されているかを確認します。拒否された場合は、NetworkタブのCookie欄に警告が表示されます。
  • HTTPで配信されているページがあると、そのページでは Secure 付きCookieが送信されません。HTTPS化とHTTP→HTTPSの恒久リダイレクト(「HTTPからHTTPSへ転送」)を先に完了させてください。

よくある質問(FAQ)

SameSite=NoneだけでSecureを付けないとどうなりますか?

現在の主要ブラウザはそのCookieを保存しません。rfc6265bisは、SameSite=NoneでSecureが無いCookieは処理を中止して完全に無視すると定めています。外部の予約ウィジェットやSSO連携などが、戻ってきたときにセッションを見つけられず失敗します。

ブラウザが拒否するなら、実害はないのではありませんか?

ブラウザの実装は一様ではなく、古い端末や組み込みブラウザ、アプリ内ブラウザでは受け入れられて平文で送信される可能性があります。また、連携機能の不具合が問い合わせ対応や、セッションIDをURLに載せるといった危険な回避策を誘発します。

SameSite=NoneのCookieを使っていないサイトはどう判定されますか?

評価する対象がないため「対象外」とし、得点の加算も減点もしません。Cookie自体が無い場合も対象外です。

Partitioned属性とはどう関係しますか?

埋め込みウィジェット用のCookieにはPartitioned属性(CHIPS)を組み合わせることがあり、PartitionedもSecureが必須です。通常はSameSite=None; Secure; Partitionedの形で使います。Partitionedの要件は別項目で評価します。

HTTPのページが残っていてもSameSite=None; Secureは使えますか?

Secure付きCookieはHTTPSの接続でしか設定・送信できないため、HTTPのページでは機能しません。SameSite=Noneを使う機能は、サイト全体のHTTPS化とHTTP→HTTPSの恒久リダイレクトを先に完了させることが前提です。

セキュリティAIチェッカーを利用する

この項目を含む127項目を、URLを入れるだけで無料診断します。

参考資料