[3] [[Cookie]] 設定時の [DFN[[CODE(HTTP)@en[[[Domain]]]] [[属性]]]]は、その [[Cookie]]
の対象となる[[ドメイン名]]を指定します。 [[HTTP]] の [CODE(HTTP)@en[[[Set-Cookie:]]]] [[応答頭欄]]や
[[JavaScript]] の [CODE(JS)@en[[[document.cookie]]]] の設定時に用いられます。

* 仕様書

[REFS[
- [34] '''[CITE@en[RFC 6265 - HTTP State Management Mechanism]] ([TIME[2012-03-01 09:57:02 +09:00]] 版) <http://tools.ietf.org/html/rfc6265#section-4.1.2.3>'''
- [32] [CITE@en[RFC 6265 - HTTP State Management Mechanism]] ([TIME[2012-03-01 09:57:02 +09:00]] 版) <http://tools.ietf.org/html/rfc6265#page-9>
- [46] [CITE@en[RFC 6265 - HTTP State Management Mechanism]] ([TIME[2014-10-12 15:11:47 +09:00]] 版) <http://tools.ietf.org/html/rfc6265#section-5.2.3>
- [51] [CITE@en[RFC 6265 - HTTP State Management Mechanism]] ([TIME[2014-10-12 15:11:47 +09:00]] 版) <http://tools.ietf.org/html/rfc6265#section-5.3>
- [71] [CITE@en[RFC 7469 - Public Key Pinning Extension for HTTP]] ([TIME[2015-05-05 21:00:37 +09:00]] 版) <https://tools.ietf.org/html/rfc7469#section-4.4>
]REFS]

* 意味

[35] [CODE(HTTP)@en[[[Domain]]]] [[属性]]は、[[クッキー]]が送信されることになる[[ホスト]]を指定します。
[SRC[>>34]]

[EG[
[36] 例えば [CODE(HTTP)@en[[[Domain]]=example.com]] であれば、
[CODE[example.com]], [CODE[www.example.com]], [CODE[www.corp.example.com]]
のような[[ホスト]]に対する [[HTTP]] [[要求]]で[[クッキー]]が送信されます。 [SRC[>>34]]
]EG]

[37] [CODE(HTTP)@en[[[Domain]]]] [[属性]]がなければ、[[起源鯖]]だけに[[クッキー]]を送信するべきであることを表しています。
[SRC[>>34]]

* 構文

[FIG[
[FIGCAPTION[
[33] [[RFC 6265]] における [CODE(ABNF)@en[[[Domain]]]] [[属性]]の構文
]FIGCAPTION]

[PRE(ABNF code)[
 domain-av         = "Domain=" domain-value
 domain-value      = <[[subdomain]]>
                       ; defined in [RFC1034], Section 3.5, as
                       ; enhanced by [RFC1123], Section 2.1
]PRE]
]FIG]

** 先頭の [CODE[.]]

[38] [[RFC 6265]] の構文では先頭の [CODE[[[.]]]] は認められていません。また、先頭にあった場合には、
これを無視することになっています [SRC[>>34, >>46]]。

;;
[17] [[RFC 2109]] の定義では、[[ドメイン名]]の先頭は [CODE[[[.]]]] でなければならない
[SRC[>>14]] とされていました。
また、 [[RFC 2965]] の定義では、先頭が [CODE[[[.]]]] でなければ[[利用者エージェント]]が
[CODE[[[.]]]] を補う [SRC[>>16]] とされていました。

;; [45] 現実には先頭に [CODE[[[.]]]] をつけた[[ドメイン名]]も多々用いられています。

** 末尾の [CODE[.]]

[39] [[RFC 6265]] の構文では末尾の [CODE[[[.]]]] ([[末尾の点]]) は認められておらず、あった場合には[[属性]]全体が無視されることになっています
[SRC[>>34]]。

** IDN

[9] [[Cookie]] が定義されたのは [[IDN]] 導入の遥かに前であり、仕様上は [[IDN]]
の扱いが明確になっていません。

* 既定値

[40] [CODE(HTTP)@en[[[Domain]]]] [[属性]]を省略した場合、[[クッキー]]は[[起源鯖]]にのみ送られます。
[SRC[>>34]]

;; [8] [[Netscape]] の仕様では、 [CODE(HTTP)@en[[[Domain]]]] [[属性]]が指定されていない場合は [[Cookie]]
[[応答]]を生成した[[ホスト]]の名前が指定されたとみなす [SRC[>>1]] とされていました。
[[RFC 6265]] ではこれは誤った動作だけど[[利用者エージェント]]によってはそうすると述べられています
[SRC[>>34]]。

[EG[
[41] 例えば [CODE[[[example.com]]]] が [CODE(HTTP)@en[[[Domain]]]] [[属性]]無しの[[クッキー]]を発行した場合、
[CODE[example.com]] への[[要求]]にはこれを送信しますが、 [CODE[www.example.com]]
への[[要求]]ではこれを送信してはなりません。
]EG]

;; [19] [[RFC 2109]] によると[[request-host]]
[SRC[>>20]]、[[RFC 2965]] によると[[実効request-host]] [SRC[>>21]] になります。
その場合最初に [CODE(char)[[[.]]]] が付かないので、[[ドメイン一致]]するのはその[[ドメイン]]自体だけになります
[SRC[>>21]]。

[72] [[HTTPサーバー]]が [CODE(HTTP)@en[[[Host:]]]] の検査などを十分行っておらず、
任意の[[ドメイン名]]でアクセスできる状態になっていると、悪意のある者が自身の保有する [[DNS]]
[[ドメイン名]]に攻撃先の [[IPアドレス]]を割り当て、[[利用者]]をその[[ドメイン名]]に誘導することで、
攻撃先サービスの[[クッキー]]を当該[[ドメイン名]]下で発行させることができるかもしれません。
そのような攻撃を防ぐため、 [CODE(HTTP)@en[[[Domain]]]] [[属性]]は明示的に指定するべきかもしれません。

;; [73] もちろん、[[TLS]] を使ったり、 [CODE(HTTP)@en[[[Host:]]]]
の検査を行ったりすることが (他のセキュリティー上の問題を防ぐためにも) 重要なことには変わりありません。

* 文脈

[70] [[セッションクッキー]]その他[[セキュリティー]]的に重要な[[クッキー]]では、
[CODE(HTTP)@en[[[Domain]]]] [[属性]]を適切な範囲に設定する[['''べきです''']] [SRC[>>71]]。

* 構文解析

[47] [[属性値]]が[[空文字列]]の場合、動作は未定義ですが、
[[属性]]を無視する[['''べきです''']] [SRC[>>46]]。

[48] [[属性値]]の最初の文字が [CODE[[[.]]]] の場合、これは無視しなければ[['''なりません''']] [SRC[>>46]]。

;; [50] [[属性値]]が [CODE[[[.]]]] のみならこれにより[[空文字列]]になりますが、
>>47 は適用されないので無視はされません。

[49] [[小文字]]に変換しなければ[['''なりません''']] [SRC[>>46]]。

* 処理モデル

[59] [[クッキー]]の[[ドメイン]]は、 [CODE(HTTP)@en[[[Domain]]]]
[[属性]]の構文解析結果を使って次のように決定しなければ[['''なりません''']]
[SRC[>>51]]。
[FIG(steps)[
= [60] [CODE(HTTP)@en[[[Domain]]]] [[属性]]があれば、
最後の [CODE(HTTP)@en[[[Domain]]]] [[属性]]の値を[[ドメイン]]とします。
なければ、[[空文字列]]を[[ドメイン]]とします。
= [61] [[利用者エージェント]]が [[public suffix]] を拒むよう設定されており、
[[ドメイン]]が [[public suffix]] なら、
== [62] [[ドメイン]]が[[正準化要求ホスト]]と同じなら、[[ドメイン]]を[[空文字列]]とします。
== [63] そうでないなら、[[クッキー]]全体を無視してここで終わります。
= [64] [[ドメイン]]が[[空文字列]]でないなら、
== [65] [[正準化要求ホスト]]が[[ドメイン]]に[[ドメイン一致]]し''ない''なら、
[[クッキー]]全体を無視してここで終わります。
== [52] そうでないなら、
=== [53] [[クッキー]]のホストのみフラグを設定しません。
=== [54] [[クッキー]]の[[ドメイン]]を[[ドメイン]]に設定します。
= [55] そうでないなら、
== [56] [[クッキー]]のホストのみフラグを設定します。
== [57] [[クッキー]]の[[ドメイン]]を[[正準化要求ホスト]]に設定します。
]FIG]

;; [58] >>61 で [[public suffix]] が設定依存とされているのは謎ですが、
[[セキュリティー]]上、実際には有効にしなければ危険です。
([[Public Suffix List]] が [[IETF]] の標準でないといったような政治的な理由でしょうか。)

[12] [[ポート番号]]は[[クッキー]]の処理には影響しません。

;; [18] [[RFC 2965]] では別に [CODE(HTTP)@en[[[Port]]]] [[属性]]が用意されていますが、
実装されませんでした。

* 第三者クッキー

[6] [CODE(HTTP)@en[[[Domain]]]] で指定された[[ドメイン]]に属する[[ホスト]]だけがその[[ドメイン]]の
[[Cookie]] を設定することができます。 [SRC[>>1]]
[[利用者エージェント]]は [CODE(HTTP)@en[[[Domain]]]] [[属性]]の範囲外の[[起源鯖]]からの[[クッキー]]を拒否します
[SRC[>>34]]。

[EG[
[42] 例えば、 [CODE[foo.example.com]] が[[起源鯖]]の場合、 [CODE[[[Domain]]=example.com]] や
[CODE[[[Domain]]=foo.example.com]] は認められますが、 [CODE[[[Domain]]=bar.example.com]] や
[CODE[[[Domain]]=baz.foo.example.com]] の[[クッキー]]は無視されます。 [SRC[>>34]]
]EG]

;; [22] [[RFC 2109]] では、[CODE(HTTP)@en[[[Domain]]]] が途中に [CODE[[[.]]]]
を含まない場合や [CODE[[[.]]]] から始まらない場合にはその [[Cookie]]
を[RUBYB[[[蓄積]]]@en[store]]しては[['''ならない''']]とされていました
[SRC[>>23]]。

;; [25] [[RFC 2965]] では [CODE(HTTP)@en[[[Domain]]]] が途中に [CODE[[[.]]]]
を含まない場合でその値が [CODE(HTTP)@en[[[.local]]]] ではない時にその [[Cookie]]
を[RUBYB[[[蓄積]]]@en[store]]しては[['''ならない''']]とされていました [SRC[>>24]]。

;; [26] 更に、 [[RFC 2109]] では [CODE(HTTP)@en[[[Domain]]]] が [[request-host]]
と[[ドメイン一致]]しない場合、 [[RFC 2965]] では [CODE(HTTP)@en[[[Domain]]]] が
[[request-host]] の[[実効ホスト名]]と[[ドメイン一致]]しない場合に、その [[Cookie]]
を[RUBYB[[[蓄積]]]@en[store]]しては[['''ならない''']]とされていました [SRC[>>23、>>24]]。

;; [27] 加えて、[[RFC 2109]] と [[RFC 2965]] では、 [[request-host]] が [[IPアドレス]]では''なく''、
[CODE[[[.]]]] を含まない文字列 [VAR[H]] と [CODE(HTTP)@en[[[Domain]]]] の値 [VAR[D]]
を使って [CODE[[VAR[H]][VAR[D]]]] と表せる場合に、その [[Cookie]]
を[RUBYB[[[蓄積]]]@en[store]]しては[['''ならない''']]とされていました [SRC[>>23、>>24]]。

** TLD

[7] [CODE(HTTP)@en[[[Domain]]]] で設定する[[ドメイン名]]には少なくても2つか3つの [CODE(char)[[[.]]]]
が含まれていなければなりません。基本的には3つ以上で、2つでもよいのは
[CODE@en[[[.com]]]], [CODE@en[[[.edu]]]], [CODE@en[[[.net]]]], [CODE@en[[[.org]]]],
[CODE@en[[[.gov]]]], [CODE@en[[[.mil]]]], [CODE@en[[[.int]]]] の7つの [[gTLD]] だけです。
[SRC[>>1]]

[10] [[FQDN]] であることを明示する際に [CODE[foo.example.]] のように最後に [CODE[[[.]]]]
を付けることがありますが、これと >>4 の処理モデルや >>7 の制約との関係は仕様上明確にされていません。

* 歴史

** Netscape Cookie

[4] [[妥当]]な [[Cookie]] を探す際に、[[Cookie]] の [CODE(HTTP)@en[[[Domain]]]]
[[属性]]と、 [[fetch]] しようとしている [[URL]] の[[ドメイン名]]の部分とを比較します。
ここで[[末尾一致]]していれば、更に [CODE(HTTP)@en[[[Path]]]] の比較へと進みます。
[SRC[>>1]] 一致していなければその [[Cookie]] は妥当ではなく、[[HTTP]]
[[要求]]の [CODE(HTTP)@en[[[Cookie:]]]] [[頭欄]]には含まれません。

[5] ここで[DFN[[RUBYB[[[末尾一致]]]@en[tail matching]]]]とは、
[[fetch]] しようとしている[[ホスト]]の[[完全修飾ドメイン名]] ([[FQDN]])
の末尾に [CODE(HTTP)@en[[[Domain]]]] [[属性]]の値が一致することをいいます。 [SRC[>>1]]

;; 例えば、 [CODE(HTTP)@en[[[Domain]]=acme.com]] は 
[CODE@en[anvil.acme.com]] や [CODE@en[shipping.crate.acme.com]] と一致します。 [SRC[>>1]]

[11] 仕様上明記されていませんが、[[ドメイン名]]は[[大文字・小文字を区別しない]]ので、
この[[一致]]の際も差異は無視されるものと思われます。

[REFS[
-[1] [[Netscape Cookie]]: [CITE[Client Side State - HTTP Cookies]]
<http://web.archive.org/web/19961125090609/http://www2.netscape.com/newsref/std/cookie_spec.html>
]REFS]

** RFC 2109 の [CODE(HTTP)@en[Set-Cookie]] の定義

[31] [[RFC 2109]], [[RFC 2965]] では、[[利用者エージェント]]には異なる[[ドメイン]]の[[ホスト]]での[[セッション]]情報の共有を可能な限り阻止する[['''べき''']]
[SRC[>>30, >>29]] とのよくわからない要件が課されていました。

*** 仕様書

- [13] [DEL[[[RFC 2109]]]] ([[廃止]]済み)
-- [14] '''[CSECTION@en[4.2.2 Set-Cookie2 Syntax]]'''
-- [20] [CSECTION@en[4.3.1 Interpreting Set-Cookie2]]
-- [23] [CSECTION@en[4.3.2 Rejecting Cookies]]
-- [30] [CSECTION@en[8.3  Unexpected Cookie Sharing]]

** RFC 2965 の [CODE(HTTP)@en[Set-Cookie2] の定義

*** 仕様書

- [15] [[RFC 2965]]
-- [16] '''[CSECTION@en[3.2.2 Set-Cookie2 Syntax]]'''
-- [21] [CSECTION@en[3.3.1 Interpreting Set-Cookie2]]
-- [24] [CSECTION@en[3.3.2 Rejecting Cookies]]
-- [29] [CSECTION@en[7.3  Unexpected Cookie Sharing]]

* 関連

[28] [[RFC 2109]]、[[RFC 2965]] では[[利用者エージェント]]が返送する時に
[CODE(HTTP)@en[[[Cookie:]]]] に [CODE(HTTP)@en[[[$Domain]]]] [[属性]]として含めることになっていました。

* メモ

[2] 
[CITE[document.cookie の覚え書き - Ci.nsIZIGOROu - Mozilla 拡張機能勉強会]] ([TIME[2009-02-01 18:27:09 +09:00]] 版) <http://moz-addon.g.hatena.ne.jp/ZIGOROu/20081001/1222845305>

>現在 test.example.com で実行してるとして、
[PRE(JS example code)[
document.cookie = "Z=1";
alert(document.cookie);
document.cookie = "Z=2;domain=example.com";
alert(document.cookie);
document.cookie = "Z=3;domain=test.example.com";
alert(document.cookie);
]PRE]
は IE6, 7 の場合、最終的に "Z=3;Z=2" となるのだが、Fx3, Safari だと、"Z=1;Z=2;Z=3" となる。
>domain が省略された場合、test.example.com 相当で設定したとされるべきだと思うんだけど。
>
と思ったら、domain パラメータの挙動について見ている所が netscape の決めた奴と言う古い奴見てた事が判明。
>>
:Domain=domain:Optional. The Domain attribute specifies the domain for which the cookie is valid. An explicitly specified domain must always start with a dot. 
>>    RFC 2109 - 4.2.2 Set-Cookie Syntax
>つまり、指定するなら "." から開始しないとだめぽって事。
>省略した場合の挙動は、
>>    Domain Defaults to the request-host. (Note that there is no dot at the beginning of request-host.)
>>RFC 2109 - 4.3.1 Interpreting Set-Cookie
>"." を先頭につけないのが正しいと。
>[DEL[まぁこれらの結果分かるのは、domain 指定がある場合、別々の物として key-value のペアが管理されますよと考えられると。]]
>[INS[この挙動、IEとそれ以外でだいぶ異なるみたいなので注意]]

[43] [CITE[252342 – fix cookie domain checks to not allow .co.uk]]
( ([TIME[2012-03-25 11:29:16 +09:00]] 版))
<https://bugzilla.mozilla.org/show_bug.cgi?id=252342>

[44] [CITE@en[draft-pettersen-dns-cookie-validate-05 - Enhanced validation of domains for HTTP State Management Cookies using DNS]]
( ([TIME[2012-03-19 18:25:41 +09:00]] 版))
<http://tools.ietf.org/html/draft-pettersen-dns-cookie-validate-05>

[66] [CITE@en[draft-pettersen-dns-cookie-validate-05 - Enhanced validation of domains for HTTP State Management Cookies using DNS]]
( ([TIME[2014-10-16 13:01:02 +09:00]] 版))
<http://tools.ietf.org/html/draft-pettersen-dns-cookie-validate-05>

[67] [CITE@en[draft-pettersen-dns-cookie-validate-05 - Enhanced validation of domains for HTTP State Management Cookies using DNS]]
( ([TIME[2014-10-16 13:01:02 +09:00]] 版))
<http://tools.ietf.org/html/draft-pettersen-dns-cookie-validate-05>

[68] [CITE@en[RFC 2964 - Use of HTTP State Management]]
( ([TIME[2014-09-07 21:45:30 +09:00]] 版))
<http://tools.ietf.org/html/rfc2964#section-3.2>

[69] [CITE[Issue 56211 - chromium - chrome.cookies fails for localhost domains - An open-source project to help move the web forward. - Google Project Hosting]]
([TIME[2015-04-20 21:13:38 +09:00]] 版)
<https://code.google.com/p/chromium/issues/detail?id=56211>

[74] [CITE@ja[Intent to Deprecate and Remove: Non-ASCII characters in cookie domain attributes]], [TIME[2022-07-25T10:10:39.000Z]] <https://groups.google.com/a/chromium.org/g/blink-dev/c/x3DY-PuZhNw>
