[インデックス 17390] ファイルの概要
このコミットは、Go言語の標準ライブラリ net/http
パッケージにおけるクッキーの Domain
属性の扱いに関する修正です。具体的には、Set-Cookie
ヘッダーを送信する際に、クッキーの Domain
属性の先頭に付与されるドット (.
) を取り除くように変更されました。これは、RFC 6265 の仕様に準拠するための修正です。
コミット
commit f1d61b959fc0f759a619025eebd3c76d8a897553
Author: Volker Dobler <dr.volker.dobler@gmail.com>
Date: Mon Aug 26 07:41:37 2013 -0500
net/http: do not send leading dot in cookie domain attribute
RFC 6265 allows a leading dot in a cookie domain attribute
but is clear (see section 4.1.1) that a Set-Cookie header
should be sent without these dots.
R=bradfitz
CC=golang-dev
https://golang.org/cl/13111043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f1d61b959fc0f759a619025eebd3c76d8a897553
元コミット内容
net/http: do not send leading dot in cookie domain attribute
RFC 6265 では、クッキーのドメイン属性に先頭のドットを許可していますが、Set-Cookie
ヘッダーはこれらのドットなしで送信されるべきであると明確に述べています(セクション 4.1.1 を参照)。
変更の背景
この変更の背景には、HTTP クッキーの仕様を定めた RFC 6265 への準拠があります。RFC 6265 は、クッキーの Domain
属性の解釈と送信方法について詳細に規定しています。
以前の Go の net/http
パッケージでは、Cookie
構造体の Domain
フィールドに先頭のドットが含まれている場合、そのドットを含んだまま Set-Cookie
ヘッダーとして送信していました。しかし、RFC 6265 のセクション 4.1.1「The Set-Cookie Header Field」では、Domain
属性の値は「ドットで始まってはならない」と明記されています。
具体的には、RFC 6265 のセクション 4.1.1.2「The Domain Attribute」には、以下のような記述があります。
If the attribute-name is "Domain", the attribute-value is the domain-value. The domain-value is a string that represents a host domain name. If the domain-value is empty, the user agent will apply the default domain. If the domain-value starts with a %x2E (".") character, the user agent will ignore the Domain attribute.
この記述は、Set-Cookie
ヘッダーで送信される Domain
属性の値がドットで始まる場合、ユーザーエージェント(ブラウザなど)がその Domain
属性を無視する可能性があることを示唆しています。つまり、先頭にドットが付いた Domain
属性を持つクッキーは、意図した通りに機能しないか、ホストオンリークッキーとして扱われる可能性がありました。
このコミットは、この仕様の不一致を解消し、Go の net/http
パッケージが生成する Set-Cookie
ヘッダーが RFC 6265 に完全に準拠するようにするために行われました。これにより、異なるブラウザやクライアント間でのクッキーの互換性と予測可能性が向上します。
前提知識の解説
HTTP クッキー (HTTP Cookies)
HTTP クッキーは、ウェブサイトがユーザーのブラウザに保存する小さなデータのことです。主にセッション管理(ログイン状態の維持)、パーソナライゼーション(ユーザー設定の記憶)、トラッキング(ユーザー行動の追跡)などに利用されます。
Set-Cookie
ヘッダー
サーバーがクライアント(ブラウザ)にクッキーを設定する際に使用する HTTP レスポンスヘッダーです。このヘッダーには、クッキーの名前、値、有効期限、パス、ドメインなどの属性が含まれます。
例:
Set-Cookie: name=value; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Domain=example.com; Path=/
クッキーの Domain
属性
Domain
属性は、クッキーが送信されるドメインを指定します。
Domain
属性が指定されていない場合、クッキーは「ホストオンリークッキー」となり、クッキーを設定したサーバーのホスト名にのみ送信されます。サブドメインには送信されません。Domain
属性が指定されている場合、クッキーはそのドメインと、そのドメインのすべてのサブドメインに送信されます。例えば、Domain=example.com
と設定されたクッキーは、example.com
、www.example.com
、sub.example.com
などに送信されます。
RFC 6265
RFC 6265 は、HTTP State Management Mechanism (HTTP 状態管理メカニズム) を定義する標準ドキュメントです。これは、HTTP クッキーの動作に関する最新かつ最も権威ある仕様であり、クッキーの作成、送信、保存、およびアクセスに関する詳細なルールを定めています。この RFC は、以前のクッキーに関する非公式な仕様や実装の不整合を解消し、より堅牢で安全なクッキーの利用を促進することを目的としています。
特に、Domain
属性に関するセクション 4.1.1.2 は、クッキーのドメインマッチングのルールと、Set-Cookie
ヘッダーで送信される Domain
属性の値の形式について重要な指針を提供しています。
ホストオンリークッキー (Host-only Cookie)
Domain
属性が明示的に指定されていないクッキーは、ホストオンリークッキーと呼ばれます。これらのクッキーは、クッキーを設定したオリジンサーバーの完全なホスト名にのみ送信され、そのサブドメインには送信されません。例えば、www.example.com
から設定されたホストオンリークッキーは、www.example.com
には送信されますが、example.com
や sub.example.com
には送信されません。
技術的詳細
このコミットの技術的な核心は、net/http
パッケージが Set-Cookie
ヘッダーを生成する際に、Cookie
構造体の Domain
フィールドの先頭にドットが存在するかどうかをチェックし、存在する場合はそのドットを取り除いてからヘッダーに含める点にあります。
RFC 6265 のセクション 4.1.1.2 では、Domain
属性の値がドットで始まる場合、ユーザーエージェントがその Domain
属性を無視する可能性があると述べられています。これは、Set-Cookie
ヘッダーの Domain
属性が、常にドットなしの形式で送信されるべきであることを意味します。例えば、Domain=.example.com
ではなく、Domain=example.com
として送信されるべきです。
この修正により、Go の net/http
パッケージは、開発者が Cookie
構造体の Domain
フィールドに ".example.com"
のように先頭にドットを含む値を設定した場合でも、RFC 6265 に準拠した Set-Cookie
ヘッダーを生成するようになります。これにより、クッキーの動作がより予測可能になり、異なるクライアント環境での互換性の問題が減少します。
具体的には、Cookie.String()
メソッド内で c.Domain
の値が有効なクッキーのドメインであると判断された後、その文字列の最初の文字がドットであるかどうかがチェックされます。もしドットであれば、そのドットを削除した部分文字列が Set-Cookie
ヘッダーの Domain
属性の値として使用されます。これにより、内部的にはドットを含む Domain
値を保持しつつも、外部に送信される形式は標準に準拠するようになります。
この変更は、クッキーのセキュリティやプライバシーに直接的な影響を与えるものではありませんが、クッキーの機能的な互換性と標準への準拠を保証する上で重要です。
コアとなるコードの変更箇所
src/pkg/net/http/cookie.go
--- a/src/pkg/net/http/cookie.go
+++ b/src/pkg/net/http/cookie.go
@@ -149,8 +149,13 @@ func (c *Cookie) String() string {
if validCookieDomain(c.Domain) {
// A c.Domain containing illegal characters is not
// sanitized but simply dropped which turns the cookie
- // into a host-only cookie.
- fmt.Fprintf(&b, "; Domain=%s", c.Domain)
+ // into a host-only cookie. A leading dot is okay
+ // but won't be sent.
+ d := c.Domain
+ if d[0] == '.' {
+ d = d[1:]
+ }
+ fmt.Fprintf(&b, "; Domain=%s", d)
} else {
log.Printf("net/http: invalid Cookie.Domain %q; dropping domain attribute",
c.Domain)
src/pkg/net/http/cookie_test.go
--- a/src/pkg/net/http/cookie_test.go
+++ b/src/pkg/net/http/cookie_test.go
@@ -26,7 +26,7 @@ var writeSetCookiesTests = []struct {
},
{
&Cookie{Name: "cookie-3", Value: "three", Domain: ".example.com"},
- "cookie-3=three; Domain=.example.com",
+ "cookie-3=three; Domain=example.com",
},
{
&Cookie{Name: "cookie-4", Value: "four", Path: "/restricted/"},
コアとなるコードの解説
src/pkg/net/http/cookie.go
の変更
Cookie
構造体の String()
メソッドは、Cookie
オブジェクトを Set-Cookie
ヘッダーの文字列形式に変換する役割を担っています。このメソッド内で、Domain
属性の処理が変更されました。
変更前:
fmt.Fprintf(&b, "; Domain=%s", c.Domain)
c.Domain
の値がそのまま Domain
属性としてフォーマットされていました。もし c.Domain
が ".example.com"
であれば、Set-Cookie
ヘッダーには Domain=.example.com
が含まれていました。
変更後:
// into a host-only cookie. A leading dot is okay
// but won't be sent.
d := c.Domain
if d[0] == '.' {
d = d[1:]
}
fmt.Fprintf(&b, "; Domain=%s", d)
d := c.Domain
: まず、c.Domain
の値を一時変数d
にコピーします。if d[0] == '.'
:d
の最初の文字がドット (.
) であるかをチェックします。d = d[1:]
: もし最初の文字がドットであれば、スライス操作d[1:]
を用いて、最初の文字(ドット)を取り除いた残りの文字列をd
に再代入します。fmt.Fprintf(&b, "; Domain=%s", d)
: 最後に、修正された(または元のままの)d
の値をDomain
属性としてフォーマットします。
この変更により、Cookie
オブジェクトの Domain
フィールドが ".example.com"
であっても、実際に Set-Cookie
ヘッダーとして送信される際には Domain=example.com
となり、RFC 6265 の要件に準拠するようになります。コメント A leading dot is okay but won't be sent.
は、内部的には先頭ドットを許容しつつも、送信時には取り除くという意図を明確に示しています。
src/pkg/net/http/cookie_test.go
の変更
テストファイル cookie_test.go
では、writeSetCookiesTests
というテストケースのスライスが定義されており、様々な Cookie
オブジェクトがどのように Set-Cookie
ヘッダー文字列に変換されるかを検証しています。
変更前:
{
&Cookie{Name: "cookie-3", Value: "three", Domain: ".example.com"},
"cookie-3=three; Domain=.example.com",
},
Domain
が ".example.com"
の場合、期待される出力も Domain=.example.com
でした。これは、変更前の実装の動作を反映しています。
変更後:
{
&Cookie{Name: "cookie-3", Value: "three", Domain: ".example.com"},
"cookie-3=three; Domain=example.com",
},
Domain
が ".example.com"
の場合でも、期待される出力が Domain=example.com
に変更されました。これは、cookie.go
で行われた修正が正しく機能し、先頭のドットが取り除かれることを検証するための変更です。このテストケースの更新は、コードの変更が意図した通りに動作することを保証するために不可欠です。
関連リンク
- Go CL 13111043: https://golang.org/cl/13111043 - このコミットに対応する Go のコードレビューシステム (Gerrit) のチェンジリスト。詳細な議論やレビューコメントが確認できます。
- RFC 6265 - HTTP State Management Mechanism: https://datatracker.ietf.org/doc/html/rfc6265 - HTTP クッキーの公式仕様。特にセクション 4.1.1.2 "The Domain Attribute" を参照。
参考にした情報源リンク
- RFC 6265: HTTP State Management Mechanism - https://datatracker.ietf.org/doc/html/rfc6265
- Go のソースコード (net/http/cookie.go, net/http/cookie_test.go) - https://github.com/golang/go
- Go のコードレビューシステム (Gerrit) - https://golang.org/cl/
- MDN Web Docs: Set-Cookie - https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Set-Cookie
- MDN Web Docs: HTTP cookies - https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies
- Stack Overflow や技術ブログ記事など、RFC 6265 の
Domain
属性に関する解説記事。# [インデックス 17390] ファイルの概要
このコミットは、Go言語の標準ライブラリ net/http
パッケージにおけるクッキーの Domain
属性の扱いに関する修正です。具体的には、Set-Cookie
ヘッダーを送信する際に、クッキーの Domain
属性の先頭に付与されるドット (.
) を取り除くように変更されました。これは、RFC 6265 の仕様に準拠するための修正です。
コミット
commit f1d61b959fc0f759a619025eebd3c76d8a897553
Author: Volker Dobler <dr.volker.dobler@gmail.com>
Date: Mon Aug 26 07:41:37 2013 -0500
net/http: do not send leading dot in cookie domain attribute
RFC 6265 allows a leading dot in a cookie domain attribute
but is clear (see section 4.1.1) that a Set-Cookie header
should be sent without these dots.
R=bradfitz
CC=golang-dev
https://golang.org/cl/13111043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f1d61b959fc0f759a619025eebd3c76d8a897553
元コミット内容
net/http: do not send leading dot in cookie domain attribute
RFC 6265 では、クッキーのドメイン属性に先頭のドットを許可していますが、Set-Cookie
ヘッダーはこれらのドットなしで送信されるべきであると明確に述べています(セクション 4.1.1 を参照)。
変更の背景
この変更の背景には、HTTP クッキーの仕様を定めた RFC 6265 への準拠があります。RFC 6265 は、クッキーの Domain
属性の解釈と送信方法について詳細に規定しています。
以前の Go の net/http
パッケージでは、Cookie
構造体の Domain
フィールドに先頭のドットが含まれている場合、そのドットを含んだまま Set-Cookie
ヘッダーとして送信していました。しかし、RFC 6265 のセクション 4.1.1「The Set-Cookie Header Field」では、Domain
属性の値は「ドットで始まってはならない」と明記されています。
具体的には、RFC 6265 のセクション 4.1.1.2「The Domain Attribute」には、以下のような記述があります。
If the attribute-name is "Domain", the attribute-value is the domain-value. The domain-value is a string that represents a host domain name. If the domain-value is empty, the user agent will apply the default domain. If the domain-value starts with a %x2E (".") character, the user agent will ignore the Domain attribute.
この記述は、Set-Cookie
ヘッダーで送信される Domain
属性の値がドットで始まる場合、ユーザーエージェント(ブラウザなど)がその Domain
属性を無視する可能性があることを示唆しています。つまり、先頭にドットが付いた Domain
属性を持つクッキーは、意図した通りに機能しないか、ホストオンリークッキーとして扱われる可能性がありました。
このコミットは、この仕様の不一致を解消し、Go の net/http
パッケージが生成する Set-Cookie
ヘッダーが RFC 6265 に完全に準拠するようにするために行われました。これにより、異なるブラウザやクライアント間でのクッキーの互換性と予測可能性が向上します。
前提知識の解説
HTTP クッキー (HTTP Cookies)
HTTP クッキーは、ウェブサイトがユーザーのブラウザに保存する小さなデータのことです。主にセッション管理(ログイン状態の維持)、パーソナライゼーション(ユーザー設定の記憶)、トラッキング(ユーザー行動の追跡)などに利用されます。
Set-Cookie
ヘッダー
サーバーがクライアント(ブラウザ)にクッキーを設定する際に使用する HTTP レスポンスヘッダーです。このヘッダーには、クッキーの名前、値、有効期限、パス、ドメインなどの属性が含まれます。
例:
Set-Cookie: name=value; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Domain=example.com; Path=/
クッキーの Domain
属性
Domain
属性は、クッキーが送信されるドメインを指定します。
Domain
属性が指定されていない場合、クッキーは「ホストオンリークッキー」となり、クッキーを設定したサーバーのホスト名にのみ送信されます。サブドメインには送信されません。Domain
属性が指定されている場合、クッキーはそのドメインと、そのドメインのすべてのサブドメインに送信されます。例えば、Domain=example.com
と設定されたクッキーは、example.com
、www.example.com
、sub.example.com
などに送信されます。
RFC 6265
RFC 6265 は、HTTP State Management Mechanism (HTTP 状態管理メカニズム) を定義する標準ドキュメントです。これは、HTTP クッキーの動作に関する最新かつ最も権威ある仕様であり、クッキーの作成、送信、保存、およびアクセスに関する詳細なルールを定めています。この RFC は、以前のクッキーに関する非公式な仕様や実装の不整合を解消し、より堅牢で安全なクッキーの利用を促進することを目的としています。
特に、Domain
属性に関するセクション 4.1.1.2 は、クッキーのドメインマッチングのルールと、Set-Cookie
ヘッダーで送信される Domain
属性の値の形式について重要な指針を提供しています。
ホストオンリークッキー (Host-only Cookie)
Domain
属性が明示的に指定されていないクッキーは、ホストオンリークッキーと呼ばれます。これらのクッキーは、クッキーを設定したオリジンサーバーの完全なホスト名にのみ送信され、そのサブドメインには送信されません。例えば、www.example.com
から設定されたホストオンリークッキーは、www.example.com
には送信されますが、example.com
や sub.example.com
には送信されません。
技術的詳細
このコミットの技術的な核心は、net/http
パッケージが Set-Cookie
ヘッダーを生成する際に、Cookie
構造体の Domain
フィールドの先頭にドットが存在するかどうかをチェックし、存在する場合はそのドットを取り除いてからヘッダーに含める点にあります。
RFC 6265 のセクション 4.1.1.2 では、Domain
属性の値がドットで始まる場合、ユーザーエージェントがその Domain
属性を無視する可能性があると述べられています。これは、Set-Cookie
ヘッダーの Domain
属性が、常にドットなしの形式で送信されるべきであることを意味します。例えば、Domain=.example.com
ではなく、Domain=example.com
として送信されるべきです。
この修正により、Go の net/http
パッケージは、開発者が Cookie
構造体の Domain
フィールドに ".example.com"
のように先頭にドットを含む値を設定した場合でも、RFC 6265 に準拠した Set-Cookie
ヘッダーを生成するようになります。これにより、クッキーの動作がより予測可能になり、異なるクライアント環境での互換性の問題が減少します。
具体的には、Cookie.String()
メソッド内で c.Domain
の値が有効なクッキーのドメインであると判断された後、その文字列の最初の文字がドットであるかどうかがチェックされます。もしドットであれば、そのドットを削除した部分文字列が Set-Cookie
ヘッダーの Domain
属性の値として使用されます。これにより、内部的にはドットを含む Domain
値を保持しつつも、外部に送信される形式は標準に準拠するようになります。
この変更は、クッキーのセキュリティやプライバシーに直接的な影響を与えるものではありませんが、クッキーの機能的な互換性と標準への準拠を保証する上で重要です。
コアとなるコードの変更箇所
src/pkg/net/http/cookie.go
--- a/src/pkg/net/http/cookie.go
+++ b/src/pkg/net/http/cookie.go
@@ -149,8 +149,13 @@ func (c *Cookie) String() string {
if validCookieDomain(c.Domain) {
// A c.Domain containing illegal characters is not
// sanitized but simply dropped which turns the cookie
- // into a host-only cookie.
- fmt.Fprintf(&b, "; Domain=%s", c.Domain)
+ // into a host-only cookie. A leading dot is okay
+ // but won't be sent.
+ d := c.Domain
+ if d[0] == '.' {
+ d = d[1:]
+ }
+ fmt.Fprintf(&b, "; Domain=%s", d)
} else {
log.Printf("net/http: invalid Cookie.Domain %q; dropping domain attribute",
c.Domain)
src/pkg/net/http/cookie_test.go
--- a/src/pkg/net/http/cookie_test.go
+++ b/src/pkg/net/http/cookie_test.go
@@ -26,7 +26,7 @@ var writeSetCookiesTests = []struct {
},
{
&Cookie{Name: "cookie-3", Value: "three", Domain: ".example.com"},
- "cookie-3=three; Domain=.example.com",
+ "cookie-3=three; Domain=example.com",
},
{
&Cookie{Name: "cookie-4", Value: "four", Path: "/restricted/"},\
コアとなるコードの解説
src/pkg/net/http/cookie.go
の変更
Cookie
構造体の String()
メソッドは、Cookie
オブジェクトを Set-Cookie
ヘッダーの文字列形式に変換する役割を担っています。このメソッド内で、Domain
属性の処理が変更されました。
変更前:
fmt.Fprintf(&b, "; Domain=%s", c.Domain)
c.Domain
の値がそのまま Domain
属性としてフォーマットされていました。もし c.Domain
が ".example.com"
であれば、Set-Cookie
ヘッダーには Domain=.example.com
が含まれていました。
変更後:
// into a host-only cookie. A leading dot is okay
// but won't be sent.
d := c.Domain
if d[0] == '.' {
d = d[1:]
}
fmt.Fprintf(&b, "; Domain=%s", d)
d := c.Domain
: まず、c.Domain
の値を一時変数d
にコピーします。if d[0] == '.'
:d
の最初の文字がドット (.
) であるかをチェックします。d = d[1:]
: もし最初の文字がドットであれば、スライス操作d[1:]
を用いて、最初の文字(ドット)を取り除いた残りの文字列をd
に再代入します。fmt.Fprintf(&b, "; Domain=%s", d)
: 最後に、修正された(または元のままの)d
の値をDomain
属性としてフォーマットします。
この変更により、Cookie
オブジェクトの Domain
フィールドが ".example.com"
であっても、実際に Set-Cookie
ヘッダーとして送信される際には Domain=example.com
となり、RFC 6265 の要件に準拠するようになります。コメント A leading dot is okay but won't be sent.
は、内部的には先頭ドットを許容しつつも、送信時には取り除くという意図を明確に示しています。
src/pkg/net/http/cookie_test.go
の変更
テストファイル cookie_test.go
では、writeSetCookiesTests
というテストケースのスライスが定義されており、様々な Cookie
オブジェクトがどのように Set-Cookie
ヘッダー文字列に変換されるかを検証しています。
変更前:
{
&Cookie{Name: "cookie-3", Value: "three", Domain: ".example.com"},
"cookie-3=three; Domain=.example.com",
},
Domain
が ".example.com"
の場合、期待される出力も Domain=.example.com
でした。これは、変更前の実装の動作を反映しています。
変更後:
{
&Cookie{Name: "cookie-3", Value: "three", Domain: ".example.com"},
"cookie-3=three; Domain=example.com",
},
Domain
が ".example.com"
の場合でも、期待される出力が Domain=example.com
に変更されました。これは、cookie.go
で行われた修正が正しく機能し、先頭のドットが取り除かれることを検証するための変更です。このテストケースの更新は、コードの変更が意図した通りに動作することを保証するために不可欠です。
関連リンク
- Go CL 13111043: https://golang.org/cl/13111043 - このコミットに対応する Go のコードレビューシステム (Gerrit) のチェンジリスト。詳細な議論やレビューコメントが確認できます。
- RFC 6265 - HTTP State Management Mechanism: https://datatracker.ietf.org/doc/html/rfc6265 - HTTP クッキーの公式仕様。特にセクション 4.1.1.2 "The Domain Attribute" を参照。
参考にした情報源リンク
- RFC 6265: HTTP State Management Mechanism - https://datatracker.ietf.org/doc/html/rfc6265
- Go のソースコード (net/http/cookie.go, net/http/cookie_test.go) - https://github.com/golang/go
- Go のコードレビューシステム (Gerrit) - https://golang.org/cl/
- MDN Web Docs: Set-Cookie - https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Set-Cookie
- MDN Web Docs: HTTP cookies - https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies
- Stack Overflow や技術ブログ記事など、RFC 6265 の
Domain
属性に関する解説記事。