• 診断項目 No.87/127
  • Cookie・セッション管理
  • 重大度 中(medium)

CookieのDomain/Path範囲とは?host-only Cookieの仕組み・サブドメインへの送信リスクと診断基準

CookieのDomain/Path範囲は、Cookieが送られるホストとパスの範囲です。Domain属性を付けるとサブドメインにも送られる理由、Pathがセキュリティ境界にならない理由、PHP・Apache・IIS・Next.jsの設定例を解説します。

結論(CookieのDomain/Path範囲)

CookieのDomain/Path範囲とは、Set-CookieのDomain属性とPath属性で決まる、Cookieが送信されるホストとURLパスの範囲です。Domain属性を付けないCookie(host-only)は発行したホストだけに送られますが、Domain属性を付けると、発行元と同じホスト名を書いた場合でもすべてのサブドメインに送られます。セッションCookieはDomain属性を付けず、可能なら __Host- 接頭辞を使うのが安全です。

この記事のポイント

  • Domain属性なし(host-only)のCookieは発行ホストと完全一致するリクエストにだけ送られます。
  • Domain属性ありのCookieは、指定ドメインとそのすべてのサブドメインに送られます(自ホスト名や先頭ドット付きでも同じ)。
  • Path属性はセキュリティの境界として頼れない(RFC 6265bis 第4.1.2.4節)ため、アプリの分離はホスト名で行います。
  • セキュリティAIチェッカーは値のあるDomain属性を持つCookieが1件でもあれば△、すべてhost-onlyなら○(重み2)と判定します。
  • PHPは session.cookie_domain を空にし、可能なら __Host- 接頭辞と Secure; Path=/ でDomain指定をブラウザに禁止させます。
診断項目名CookieのDomain/Path範囲
項目IDcookie.scope
分類Cookie・セッション管理
重大度・配点の重み中(medium) 重み 2
関連する標準・ガイドラインOWASP ASVS 5.0.0 V3.3.3(Level 2「他ホストと共有する設計でない限り、Cookie 名に __Host- 接頭辞を付けること」、Domain 属性なし=host-only が前提)、OWASP ASVS 5.0.0 V3.5.4(Level 2、別アプリは別ホスト名で運用し、Cookie のホスト制限を活かす)、OWASP WSTG-SESS-02(Testing for Cookies Attributes:Domain/Path 属性)、OWASP Session Management Cheat Sheet(Domain and Path Attributes)、RFC 6265 および RFC 6265bis(draft-ietf-httpbis-rfc6265bis-22)第4.1.2.3節(Domain)、第4.1.2.4節(Path)、第8.6節(Weak Integrity)、IPA「安全なウェブサイトの作り方」1.4 セッション管理の不備

CookieのDomain/Path範囲とは

CookieのDomain/Path範囲とは、Set-Cookie ヘッダーの Domain 属性と Path 属性によって決まる、Cookieが送信されるホストとURLパスの範囲のことです。

Domain属性送信先
なし(host-only)Cookieを発行したホストにだけ送られる。サブドメインには送られない
あり指定したドメインと、そのすべてのサブドメインに送られる

注意したいのは、Domain=www.city.example.lg.jp のように発行元と同じホスト名を書いた場合でも、xxx.www.city.example.lg.jp のようなサブドメインに広がる点です。

セッションCookieをDomain付きで発行すると、同じ親ドメイン配下の別のサーバー(委託先が運営する別システム、古いままのサブサイトなど)にもCookieが届き、そこが乗っ取られた場合に盗まれたり上書きされたりします。セキュリティAIチェッカーはこの項目で、観測した Set-Cookie に Domain 属性が付いているかを確認します。

送信範囲の例

# host-only(発行ホストだけに送られる)
Set-Cookie: PHPSESSID=abc123; Path=/; Secure; HttpOnly

# Domain 付き(city.example.lg.jp のすべてのサブドメインに送られる)
Set-Cookie: JSESSIONID=abc123; Domain=city.example.lg.jp; Path=/yoyaku

Domain属性とPath属性の仕組み

Domain属性の挙動(RFC 6265bis)

RFC 6265bis では、Domain属性がないCookieは host-only-flag が true となり、発行ホストと完全一致するリクエストにだけ送られます。Domain属性がある場合は host-only-flag が false となり、ドメイン一致(サフィックス一致)するすべてのホストに送られます。Public Suffix List に載っているドメイン(lg.jp など)を Domain に指定することは、ブラウザが拒否します。

OWASP Session Management Cheat Sheet は、Domain属性を設定せず発行元サーバーに限定することを推奨しています。example.com のような広い指定は、同じドメイン配下の別ホスト・別アプリからセッションIDを攻撃される「クロスサブドメインCookie」につながると説明しています。OWASP WSTG-SESS-02 も、Domain属性を省略すれば発行ホストが既定値になること、緩すぎる指定では脆弱な別サーバーがCookieの収集に悪用され得ることを確認項目としています。

RFC 6265bis 第8.6節(Weak Integrity)は、foo.site.example のサーバーが Domain=site.example のCookieを発行すると、bar.site.example へのリクエストにもそのCookieが送られ、bar側は自分が発行したCookieと区別できず、foo側がこれを使ってbarを攻撃できる可能性があると述べています。攻撃者のセッションIDを植え付けるセッション固定攻撃は、その代表例です。

Path属性の位置づけ

Path属性は、Cookieを送るURLパスを限定します。指定しない場合の既定値は、Cookieを発行したリクエストURLのディレクトリ部分です(例:/shinsei/login.php で発行すれば /shinsei)。つまり、Pathを省略しても送信範囲が広がることはなく、むしろ狭くなる場合があります。

一方、RFC 6265bis 第4.1.2.4節は「Path属性はセキュリティの境界として頼れない」と明記しています。第8.5節(Weak Confidentiality)が説明するとおり、ブラウザは document.cookie などHTTP以外のAPIでCookieを公開し、異なるパスから取得したリソースを分離しないため、あるパスのページから別のパスのCookieにアクセスできる場合があるからです。また第8.6節は、ブラウザが任意のPath属性を受け入れるため、Pathは完全性(上書き防止)の保護にもならないとしています。OWASP Session Management Cheat Sheet も、Pathで分けるより、セキュリティレベルの異なるアプリは別ホストで運用するよう推奨しています(ASVS 5.0.0 V3.5.4 も、別アプリは別ホスト名で運用し、Cookieのホスト制限を活かすことを求めています)。

このため本項目では、Path属性の有無や値は判定に使いません。Pathを狭く設定することは、誤送信を減らす整理としては有用です。

CookieのDomain/Pathについてよくある誤解

  • 「Domain=.www.city.example.lg.jp と先頭にドットを付けると自ホストだけに限定される」:誤りです。先頭のドットは無視され、サブドメインを含みます。
  • 「自ホスト名をDomainに書けばhost-onlyと同じ」:これも誤りです。サブドメインへ広がる点が違います。
  • 「Path=/ は危険」:一面的です。同一ホスト内の分離にはPathは役立たないため、本質的な対策はホスト分離です。

Cookieのその他の属性は、「CookieのSecure属性」、「CookieのHttpOnly属性」、「CookieのSameSite属性」、接頭辞は「Cookie接頭辞の要件」で確認します。

CookieのDomain/Path範囲の診断基準(セキュリティAIチェッカー)

取得方法

  • トップページと、トップページから見つかった同一オリジンのリンク(ログイン・管理系を優先)最大4ページ、合計最大5ページを GET で取得します。
  • 各最終応答の Set-Cookie ヘッダーをすべて集めます。
  • リダイレクト途中の応答で発行されたCookieや、JavaScript(document.cookie)で作られるCookieは観測できません。

判定条件

判定条件根拠文の例
対象外(na)巡回した応答でCookieが1件も発行されないCookieが発行されず判定できない
△ 要確認(warn)値のあるDomain属性を持つCookieが1件以上あるDomain属性ありでサブドメインにも送信されるCookieが2/3件(対象ホスト: www.city.example.lg.jp)
○ 問題なし(pass)すべてのCookieにDomain属性がない(host-only。値が空の Domain= も含む)3件すべてDomain属性なし(host-only)
  • Domain属性の値が発行ホストと同一か、親ドメインかは区別せず、いずれも△とします(どちらもサブドメインへ広がるため)。
  • Path属性は判定に使いません。

得点への影響

判定得点
○ 問題なし(pass)2点(重み2)
△ 要確認(warn)0.9点
対象外(na)採点から除外

Cookieを発行しない静的な自治体サイトでは対象外になり、得点に影響しません。

自治体サイトでの判定例

Set-Cookie の例判定
CMSが PHPSESSID=...; path=/; HttpOnly; Secure を発行○
ロードバランサーが BIGipServer...=...; path=/; Domain=.city.example.lg.jp を発行△
施設予約システムが JSESSIONID=...; Domain=city.example.lg.jp; Path=/yoyaku を発行△(予約システム以外のサブドメインにも送信)
静的HTMLのみでCookieなし対象外

CookieのDomain範囲が広いとどんなリスクがあるか

  • セッションの窃取:親ドメインにDomain指定されたセッションCookieは、同じ親ドメイン配下のどのサブドメインにも送られます。脆弱性のある別サブサイト、運用が止まったキャンペーンサイト、サブドメインテイクオーバー(DNSのCNAMEが残ったまま外部サービスを解約した状態)された名前で受け取られると、セッションを乗っ取られます。
  • セッション固定・Cookieの上書き:別サブドメインから同名のCookieをDomain付きで発行し、利用者のブラウザに攻撃者のセッションIDを植え付けることができます(RFC 6265bis 第8.6節)。
  • CSRFトークンの無効化:Cookieとフォームの値を照合する「二重送信Cookie」方式のCSRF対策は、Cookieを上書きされると突破されます。
  • 最も弱いサイトが全体の弱点に:自治体では、本庁サイト、観光・移住サイト、施設予約、電子申請、オープンデータなどが同じ親ドメインのサブドメインで、別々の事業者により運用されることが多く、最も弱いサイトが全体の弱点になりやすい構造です。

CookieのDomain/Pathの安全な設定方法(PHP・Apache・nginx・IIS・Next.js)

基本方針

  1. セッションCookie・認証Cookieには Domain 属性を付けない(host-only)。
  2. 可能なら Cookie名に __Host- 接頭辞を付け、Secure; Path=/ を付与して、Domain指定をブラウザに禁止させる(ASVS 5.0.0 V3.3.3)。
  3. 複数サブドメインで共有が必要なCookieは、共有が本当に必要か見直し、必要な場合でもセッションIDとは分ける。

PHP

session_set_cookie_params([
    'lifetime' => 0,
    'path'     => '/',
    'domain'   => '',      // 空文字で Domain 属性を出さない
    'secure'   => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);
session_start();

php.ini では session.cookie_domain =(空)にします。

Apache(mod_headersで既存のDomain属性を削除)

<IfModule mod_headers.c>
  # アプリ側で直せない場合の暫定策:Set-Cookie から Domain 属性を取り除く
  # mod_php・mod_proxy 経由の Set-Cookie は onsuccess 側、CGI・PHP-FPM(mod_proxy_fcgi)の
  # Set-Cookie は always 側の表に入るため、両方に書く(2回目は対象がなければ何もしない)
  Header edit* Set-Cookie "(?i);\s*domain=[^;]*" ""
  Header always edit* Set-Cookie "(?i);\s*domain=[^;]*" ""
</IfModule>

nginx(リバースプロキシ構成)

nginx の proxy_cookie_domain は、Domain属性の値を別の値へ書き換える機能で、属性そのものを確実に取り除く用途には向きません。nginx の背後にあるアプリケーション(PHP、Java、.NET 等)の設定で Domain 属性を出さないように修正するのが確実です。どうしても書き換えが必要な場合は、書き換え後の値が親ドメインにならないこと(少なくとも発行ホスト名そのものになること)を curl で確認してください。

location / {
    proxy_pass http://app_backend;
    # 例:バックエンドが親ドメインを指定してくる場合に、発行ホスト名へ狭める
    proxy_cookie_domain city.example.lg.jp www.city.example.lg.jp;
}

IIS/ASP.NET

<system.web>
  <httpCookies domain="" requireSSL="true" httpOnlyCookies="true" />
</system.web>

Next.js(App Router)

import { cookies } from "next/headers";
(await cookies()).set("__Host-session", token, {
  httpOnly: true, secure: true, sameSite: "lax", path: "/",  // domain は指定しない
});

設定後の確認方法

curl -sI https://www.city.example.lg.jp/ | grep -i '^set-cookie'
curl -sIL https://www.city.example.lg.jp/yoyaku/login | grep -i '^set-cookie'

Domain= が出力に含まれないことを確認します。ブラウザの開発者ツール(Application → Cookies)でも、Domain列が「ホスト名のみ(先頭ドットなし)」になっていることを確認できます。

サイトを壊さないための注意点(ガードレール)

  • サブドメイン間でシングルサインオンや言語設定を共有するために Domain 属性を使っている場合、削除すると共有が切れます。共有の仕組みを OIDC 等のサーバー間連携へ移してから削除します。
  • ロードバランサーの持続性Cookie(スティッキーセッション)は、機器の設定でDomainを付けていることがあります。機器側で設定を変更してください。
  • Domain属性を外した直後は、旧Cookie(Domain付き)と新Cookie(host-only)が同名で併存することがあります。ログイン不具合が出た場合は、旧Cookieを失効(Max-Age=0、同じDomain指定)させます。
  • 使われていないサブドメインのDNSレコード(外部サービスへのCNAMEなど)を棚卸しし、サブドメインテイクオーバーを防ぎます。

よくある質問(FAQ)

CookieのDomain属性を省略するとどうなりますか?

Domain属性がないCookieはhost-onlyとなり、Cookieを発行したホストと完全一致するリクエストにだけ送られます。サブドメインには送られないため、セッションCookieにとって最も安全な設定です。

Domainに自分のホスト名を書けばhost-onlyと同じですか?

同じではありません。Domain=www.city.example.lg.jp のように発行元と同じホスト名を書いても、xxx.www.city.example.lg.jp のようなサブドメインへ広がります。host-onlyにするにはDomain属性自体を出さないことが必要です。

Domain=.example.jp のように先頭にドットを付けると何が変わりますか?

何も変わりません。先頭のドットは無視され、サブドメインを含めて送信されます。「先頭にドットを付けると自ホストだけに限定される」というのは誤解です。

Path属性でアプリごとにCookieを分離できますか?

セキュリティの境界としては頼れません。RFC 6265bis 第4.1.2.4節はPath属性をセキュリティの境界として頼れないと明記し、第8.5節は、document.cookie などHTTP以外のAPIを通じて、あるパスのページから別のパスのCookieにアクセスできる場合があると説明しています。セキュリティレベルの異なるアプリは別ホスト名で運用してください。

Path属性を省略すると送信範囲が広がりますか?

広がりません。省略時の既定値はCookieを発行したリクエストURLのディレクトリ部分(例:/shinsei/login.php なら /shinsei)で、むしろ狭くなる場合があります。セキュリティAIチェッカーはPath属性を判定に使いません。

サブドメイン間でログイン状態を共有しているのですが、Domain属性を外せますか?

外すと共有が切れます。シングルサインオンや言語設定の共有にDomain属性を使っている場合は、共有の仕組みをOIDC等のサーバー間連携へ移してから削除してください。

Cookieを発行しないサイトはどう判定されますか?

巡回した応答でCookieが1件も発行されない場合は対象外(na)で、得点に影響しません。静的なHTMLだけの自治体サイトはこれに当たります。

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

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

参考資料