[インデックス 13816] ファイルの概要
このコミットは、Go言語の標準ライブラリ html/template
パッケージ内の URL
型に関するドキュメントの修正を目的としています。具体的には、URL
型が参照するRFC番号をRFC 3896からRFC 3986に訂正し、さらに「URLまたはURLサブストリング」をカプセル化するという説明を追加しています。これは、Issue 3528の一部として、html/template
のセキュリティと正確性を向上させるための小さな修正です。
コミット
- コミットハッシュ:
37721cc1ce19269afb1a32bc14c51c4a4beb7b8b
- Author: Russ Cox rsc@golang.org
- Date: Thu Sep 13 10:53:00 2012 -0400
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/37721cc1ce19269afb1a32bc14c51c4a4beb7b8b
元コミット内容
html/template: fix URL doc
This is the easy part of issue 3528.
(What to do about "noescape" is the hard part, left open.)
Update #3528.
R=mikesamuel, r, dsymonds
CC=golang-dev
https://golang.org/cl/6493113
変更の背景
この変更は、Go言語の html/template
パッケージにおける URL
型のドキュメントの正確性を向上させるために行われました。コミットメッセージに「This is the easy part of issue 3528.」とあるように、これはGoのIssue 3528(html/template
のセキュリティとエスケープに関する問題)の一部として対処されたものです。
元のドキュメントでは、URL
型が「RFC 3896で定義された既知の安全なURL」をカプセル化すると記述されていました。しかし、RFC 3896は「Referrer Policy」に関するものであり、URLの構文や安全性に関するものではありません。URLの一般的な構文を定義しているのはRFC 3986です。この誤りを修正し、より正確な情報を提供することが変更の主な背景です。
また、「URLまたはURLサブストリング」という記述が追加されたのは、html/template
が文脈に応じたエスケープを行う際に、完全なURLだけでなく、URLの一部(例えばパスやクエリパラメータ)も安全に扱う必要があるためと考えられます。これにより、開発者が URL
型の意図と適用範囲をより正確に理解できるようになります。
コミットメッセージの「(What to do about "noescape" is the hard part, left open.)」という記述は、Issue 3528がより広範な問題を含んでおり、特に noescape
ディレクティブ(エスケープを無効にする機能)の扱いが複雑で、このコミットでは対処されていないことを示唆しています。これは、html/template
のセキュリティ保証を維持しつつ、柔軟性を提供することの難しさを示しています。
前提知識の解説
Go言語の html/template
パッケージ
html/template
パッケージは、Go言語でHTML出力を生成する際に、クロスサイトスクリプティング(XSS)攻撃などのセキュリティ脆弱性を自動的に防止するための機能を提供します。このパッケージは、出力されるコンテンツの文脈(HTML要素の属性値、JavaScriptコード内、URLなど)を認識し、それに応じて適切なエスケープ処理を自動的に適用します。これにより、開発者が手動でエスケープ処理を行う手間を省き、同時にセキュリティリスクを低減します。
文脈に応じたエスケープ (Context-aware Escaping)
従来のテンプレートエンジンでは、すべての特殊文字を一律にエスケープするか、開発者が手動でエスケープ処理を呼び出す必要がありました。しかし、HTMLは多様な文脈(例: HTML要素のテキストコンテンツ、属性値、JavaScriptコード、CSSスタイル、URL)を持ち、それぞれの文脈でエスケープすべき文字やルールが異なります。
文脈に応じたエスケープは、テンプレートエンジンが生成する出力の各部分がどの文脈に属するかを自動的に判断し、その文脈に最適なエスケープ処理を適用する技術です。例えば、HTML属性値内の "
は "
にエスケープされますが、JavaScript文字列内の "
は \"
にエスケープされます。html/template
はこの文脈認識能力により、開発者が意識することなく安全なHTMLを生成します。
RFC 3986 (URI Generic Syntax)
RFC 3986は、Uniform Resource Identifier (URI) の一般的な構文を定義する標準ドキュメントです。URIは、Web上のリソースを一意に識別するための文字列であり、URL (Uniform Resource Locator) はURIの一種で、リソースの場所を示すものです。RFC 3986は、URIの各コンポーネント(スキーム、オーソリティ、パス、クエリ、フラグメントなど)の構造と、予約文字・非予約文字の定義、パーセントエンコーディングのルールなどを詳細に規定しています。
html/template
の URL
型がRFC 3986を参照することは、この型がカプセル化する文字列が、URIの一般的な構文規則に準拠していることを意味します。これにより、テンプレートエンジンがURLを処理する際に、その構造と安全性を適切に検証・エスケープするための基盤となります。
javascript:
URLとXSSリスク
javascript:
スキームを持つURL(例: javascript:alert('XSS')
)は、クリックされるとブラウザでJavaScriptコードを実行します。信頼できないソースからの javascript:
URLがHTMLページに挿入されると、悪意のあるスクリプトが実行され、XSS攻撃につながる可能性があります。html/template
は、このようなセキュリティリスクを軽減するために、デフォルトで動的な javascript:
URLをフィルタリングまたはエスケープするメカニズムを持っています。URL
型は、信頼できるソースからのURLであることを明示的に示すために使用され、これにより html/template
がそのURLを安全であると判断し、フィルタリングせずに許可する場合があります。
技術的詳細
html/template
パッケージは、Go言語のWebアプリケーションにおいて、ユーザー入力や外部データを含むHTMLを安全に生成するための重要な役割を担っています。その中心的な機能の一つが、文脈に応じた自動エスケープです。この機能は、テンプレートがレンダリングされる際に、出力されるデータの種類(HTML、JavaScript、CSS、URLなど)を識別し、それぞれの文脈で必要とされる適切なエスケープ処理を自動的に適用することで、XSS(クロスサイトスクリプティング)攻撃などの脆弱性を防ぎます。
content.go
ファイルは、html/template
パッケージ内で、様々な種類のコンテンツ(HTML、CSS、JavaScript、URLなど)を表す型を定義しています。これらの型は、テンプレートエンジンがコンテンツの「種類」を認識し、それに基づいて適切なエスケープ戦略を適用するために使用されます。例えば、HTML
型の変数はHTMLとして扱われ、その内容はエスケープされずにそのまま出力されますが、string
型の変数がHTMLコンテキストに挿入される場合は、自動的にHTMLエスケープが適用されます。
このコミットで修正された URL
型は、特にURLの文脈におけるセキュリティを保証するために導入されています。URL
型の目的は、テンプレートエンジンに対して、その値が「既知の安全なURL」であることを明示的に伝えることです。これにより、テンプレートエンジンは、そのURLをそのまま出力しても安全であると判断できます。もし URL
型が使用されず、単なる string
型の変数がURLコンテキストに挿入された場合、html/template
は潜在的な危険性(例: javascript:
スキームによるXSS)を考慮し、そのURLをフィルタリングしたり、エスケープしたりする可能性があります。
今回の変更は、URL
型のドキュメントにおける参照RFCの誤りを修正し、より正確な情報を提供することに焦点を当てています。
-
RFC 3896 から RFC 3986 への変更:
- 元のドキュメントでは
RFC 3896
を参照していましたが、これは「Referrer Policy」に関するRFCであり、URLの構文や安全性とは直接関係ありません。 - 正しいURLの一般的な構文を定義しているのは
RFC 3986
です。この修正により、URL
型がカプセル化する値が、URIの標準的な構文規則に準拠していることを明確に示します。これは、html/template
がURLを解析し、その安全性を評価する際の基盤となる知識です。
- 元のドキュメントでは
-
「URLまたはURLサブストリング」の追加:
- 元のドキュメントでは単に「URL」と記述されていましたが、
html/template
は完全なURLだけでなく、URLの一部(例: パスセグメント、クエリパラメータ、フラグメント)も安全に扱う必要があります。 - 例えば、
href="/path/to/{{.SubPath}}?param={{.QueryParam}}"
のようなテンプレートでは、.SubPath
や.QueryParam
は完全なURLではありませんが、URLの一部として扱われ、適切にエスケープされる必要があります。 - この追加により、
URL
型が完全なURLだけでなく、URLの安全な部分文字列も表現できることを明確にし、開発者がURL
型をより柔軟かつ正確に利用できるようになります。
- 元のドキュメントでは単に「URL」と記述されていましたが、
この修正は、html/template
のセキュリティメカニズムの根幹に関わるものではありませんが、開発者がパッケージを正しく理解し、安全なコードを書くためのドキュメントの正確性を高める上で非常に重要です。特に、セキュリティ関連の型や機能においては、その定義と挙動に関する正確なドキュメントが不可欠です。
コアとなるコードの変更箇所
変更は src/pkg/html/template/content.go
ファイルの1箇所のみです。
--- a/src/pkg/html/template/content.go
+++ b/src/pkg/html/template/content.go
@@ -47,7 +47,7 @@ type (
// JSStr("foo\\nbar") is fine, but JSStr("foo\\\nbar") is not.
JSStr string
- // URL encapsulates a known safe URL as defined in RFC 3896.
+ // URL encapsulates a known safe URL or URL substring (see RFC 3986).
// A URL like `javascript:checkThatFormNotEditedBeforeLeavingPage()`
// from a trusted source should go in the page, but by default dynamic
// `javascript:` URLs are filtered out since they are a frequently
コアとなるコードの解説
変更された行は、URL
型のコメント行です。
-
変更前:
// URL encapsulates a known safe URL as defined in RFC 3896.
このコメントは、
URL
型が「RFC 3896で定義された既知の安全なURL」をカプセル化すると説明していました。しかし、前述の通り、RFC 3896はURLの構文や安全性とは無関係なRFCでした。 -
変更後:
// URL encapsulates a known safe URL or URL substring (see RFC 3986).
この変更により、以下の2点が修正・追加されました。
- RFC参照の修正:
RFC 3896
がRFC 3986
に変更されました。これにより、URL
型が参照する標準が、URIの一般的な構文を定義する正しいRFCになりました。 - 「またはURLサブストリング」の追加:
URL
型が完全なURLだけでなく、URLの一部(サブストリング)も安全にカプセル化できることが明示されました。これは、html/template
がURLの様々な部分を文脈に応じてエスケープする際に、より柔軟に対応できることを示唆しています。例えば、パスやクエリパラメータなど、完全なURLではないがURLの一部として扱われるべき文字列もURL
型で表現できることを示しています。
- RFC参照の修正:
この変更は、コードの動作自体には影響を与えませんが、html/template
パッケージを使用する開発者にとって、URL
型の目的と適用範囲をより正確に理解するための重要なドキュメント修正です。特にセキュリティ関連の型においては、その定義が正確であることが、安全なアプリケーション開発に直結します。
関連リンク
- Go Issue 3528: https://github.com/golang/go/issues/3528
- Go CL 6493113: https://golang.org/cl/6493113
参考にした情報源リンク
- RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax: https://datatracker.ietf.org/doc/html/rfc3986
- RFC 3896 - Referrer Policy: https://datatracker.ietf.org/doc/html/rfc3896
- Go html/template package documentation: https://pkg.go.dev/html/template (このコミット時点のドキュメントではないが、一般的な情報源として)
- Cross-site scripting (XSS): https://developer.mozilla.org/ja/docs/Glossary/Cross-site_scripting
- Go html/template: Context-aware escaping for HTML templates: https://go.dev/blog/html-template (このコミット時点のブログではないが、
html/template
の背景を理解するのに役立つ)```markdown
[インデックス 13816] ファイルの概要
このコミットは、Go言語の標準ライブラリ html/template
パッケージ内の URL
型に関するドキュメントの修正を目的としています。具体的には、URL
型が参照するRFC番号をRFC 3896からRFC 3986に訂正し、さらに「URLまたはURLサブストリング」をカプセル化するという説明を追加しています。これは、Issue 3528の一部として、html/template
のセキュリティと正確性を向上させるための小さな修正です。
コミット
- コミットハッシュ:
37721cc1ce19269afb1a32bc14c51c4a4beb7b8b
- Author: Russ Cox rsc@golang.org
- Date: Thu Sep 13 10:53:00 2012 -0400
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/37721cc1ce19269afb1a32bc14c51c4a4beb7b8b
元コミット内容
html/template: fix URL doc
This is the easy part of issue 3528.
(What to do about "noescape" is the hard part, left open.)
Update #3528.
R=mikesamuel, r, dsymonds
CC=golang-dev
https://golang.org/cl/6493113
変更の背景
この変更は、Go言語の html/template
パッケージにおける URL
型のドキュメントの正確性を向上させるために行われました。コミットメッセージに「This is the easy part of issue 3528.」とあるように、これはGoのIssue 3528(html/template
のセキュリティとエスケープに関する問題)の一部として対処されたものです。
元のドキュメントでは、URL
型が「RFC 3896で定義された既知の安全なURL」をカプセル化すると記述されていました。しかし、RFC 3896は「Referrer Policy」に関するものであり、URLの構文や安全性に関するものではありません。URLの一般的な構文を定義しているのはRFC 3986です。この誤りを修正し、より正確な情報を提供することが変更の主な背景です。
また、「URLまたはURLサブストリング」という記述が追加されたのは、html/template
が文脈に応じたエスケープを行う際に、完全なURLだけでなく、URLの一部(例えばパスやクエリパラメータ)も安全に扱う必要があるためと考えられます。これにより、開発者が URL
型の意図と適用範囲をより正確に理解できるようになります。
コミットメッセージの「(What to do about "noescape" is the hard part, left open.)」という記述は、Issue 3528がより広範な問題を含んでおり、特に noescape
ディレクティブ(エスケープを無効にする機能)の扱いが複雑で、このコミットでは対処されていないことを示唆しています。これは、html/template
のセキュリティ保証を維持しつつ、柔軟性を提供することの難しさを示しています。
前提知識の解説
Go言語の html/template
パッケージ
html/template
パッケージは、Go言語でHTML出力を生成する際に、クロスサイトスクリプティング(XSS)攻撃などのセキュリティ脆弱性を自動的に防止するための機能を提供します。このパッケージは、出力されるコンテンツの文脈(HTML要素の属性値、JavaScriptコード内、URLなど)を認識し、それに応じて適切なエスケープ処理を自動的に適用します。これにより、開発者が手動でエスケープ処理を行う手間を省き、同時にセキュリティリスクを低減します。
文脈に応じたエスケープ (Context-aware Escaping)
従来のテンプレートエンジンでは、すべての特殊文字を一律にエスケープするか、開発者が手動でエスケープ処理を呼び出す必要がありました。しかし、HTMLは多様な文脈(例: HTML要素のテキストコンテンツ、属性値、JavaScriptコード、CSSスタイル、URL)を持ち、それぞれの文脈でエスケープすべき文字やルールが異なります。
文脈に応じたエスケープは、テンプレートエンジンが生成する出力の各部分がどの文脈に属するかを自動的に判断し、その文脈に最適なエスケープ処理を適用する技術です。例えば、HTML属性値内の "
は "
にエスケープされますが、JavaScript文字列内の "
は \"
にエスケープされます。html/template
はこの文脈認識能力により、開発者が意識することなく安全なHTMLを生成します。
RFC 3986 (URI Generic Syntax)
RFC 3986は、Uniform Resource Identifier (URI) の一般的な構文を定義する標準ドキュメントです。URIは、Web上のリソースを一意に識別するための文字列であり、URL (Uniform Resource Locator) はURIの一種で、リソースの場所を示すものです。RFC 3986は、URIの各コンポーネント(スキーム、オーソリティ、パス、クエリ、フラグメントなど)の構造と、予約文字・非予約文字の定義、パーセントエンコーディングのルールなどを詳細に規定しています。
html/template
の URL
型がRFC 3986を参照することは、この型がカプセル化する文字列が、URIの一般的な構文規則に準拠していることを意味します。これにより、テンプレートエンジンがURLを処理する際に、その構造と安全性を適切に検証・エスケープするための基盤となります。
javascript:
URLとXSSリスク
javascript:
スキームを持つURL(例: javascript:alert('XSS')
)は、クリックされるとブラウザでJavaScriptコードを実行します。信頼できないソースからの javascript:
URLがHTMLページに挿入されると、悪意のあるスクリプトが実行され、XSS攻撃につながる可能性があります。html/template
は、このようなセキュリティリスクを軽減するために、デフォルトで動的な javascript:
URLをフィルタリングまたはエスケープするメカニズムを持っています。URL
型は、信頼できるソースからのURLであることを明示的に示すために使用され、これにより html/template
がそのURLを安全であると判断し、フィルタリングせずに許可する場合があります。
技術的詳細
html/template
パッケージは、Go言語のWebアプリケーションにおいて、ユーザー入力や外部データを含むHTMLを安全に生成するための重要な役割を担っています。その中心的な機能の一つが、文脈に応じた自動エスケープです。この機能は、テンプレートがレンダリングされる際に、出力されるデータの種類(HTML、JavaScript、CSS、URLなど)を識別し、それぞれの文脈で必要とされる適切なエスケープ処理を自動的に適用することで、XSS(クロスサイトスクリプティング)攻撃などの脆弱性を防ぎます。
content.go
ファイルは、html/template
パッケージ内で、様々な種類のコンテンツ(HTML、CSS、JavaScript、URLなど)を表す型を定義しています。これらの型は、テンプレートエンジンがコンテンツの「種類」を認識し、それに基づいて適切なエスケープ戦略を適用するために使用されます。例えば、HTML
型の変数はHTMLとして扱われ、その内容はエスケープされずにそのまま出力されますが、string
型の変数がHTMLコンテキストに挿入される場合は、自動的にHTMLエスケープが適用されます。
このコミットで修正された URL
型は、特にURLの文脈におけるセキュリティを保証するために導入されています。URL
型の目的は、テンプレートエンジンに対して、その値が「既知の安全なURL」であることを明示的に伝えることです。これにより、テンプレートエンジンは、そのURLをそのまま出力しても安全であると判断できます。もし URL
型が使用されず、単なる string
型の変数がURLコンテキストに挿入された場合、html/template
は潜在的な危険性(例: javascript:
スキームによるXSS)を考慮し、そのURLをフィルタリングしたり、エスケープしたりする可能性があります。
今回の変更は、URL
型のドキュメントにおける参照RFCの誤りを修正し、より正確な情報を提供することに焦点を当てています。
-
RFC 3896 から RFC 3986 への変更:
- 元のドキュメントでは
RFC 3896
を参照していましたが、これは「Referrer Policy」に関するRFCであり、URLの構文や安全性とは直接関係ありません。 - 正しいURLの一般的な構文を定義しているのは
RFC 3986
です。この修正により、URL
型がカプセル化する値が、URIの標準的な構文規則に準拠していることを明確に示します。これは、html/template
がURLを解析し、その安全性を評価する際の基盤となる知識です。
- 元のドキュメントでは
-
「URLまたはURLサブストリング」の追加:
- 元のドキュメントでは単に「URL」と記述されていましたが、
html/template
は完全なURLだけでなく、URLの一部(例: パスセグメント、クエリパラメータ、フラグメント)も安全に扱う必要があります。 - 例えば、
href="/path/to/{{.SubPath}}?param={{.QueryParam}}"
のようなテンプレートでは、.SubPath
や.QueryParam
は完全なURLではありませんが、URLの一部として扱われ、適切にエスケープされる必要があります。 - この追加により、
URL
型が完全なURLだけでなく、URLの安全な部分文字列も表現できることを明確にし、開発者がURL
型をより柔軟かつ正確に利用できるようになります。
- 元のドキュメントでは単に「URL」と記述されていましたが、
この修正は、html/template
のセキュリティメカニズムの根幹に関わるものではありませんが、開発者がパッケージを正しく理解し、安全なコードを書くためのドキュメントの正確性を高める上で非常に重要です。特にセキュリティ関連の型や機能においては、その定義と挙動に関する正確なドキュメントが不可欠です。
コアとなるコードの変更箇所
変更は src/pkg/html/template/content.go
ファイルの1箇所のみです。
--- a/src/pkg/html/template/content.go
+++ b/src/pkg/html/template/content.go
@@ -47,7 +47,7 @@ type (
// JSStr("foo\\nbar") is fine, but JSStr("foo\\\nbar") is not.
JSStr string
- // URL encapsulates a known safe URL as defined in RFC 3896.
+ // URL encapsulates a known safe URL or URL substring (see RFC 3986).
// A URL like `javascript:checkThatFormNotEditedBeforeLeavingPage()`
// from a trusted source should go in the page, but by default dynamic
// `javascript:` URLs are filtered out since they are a frequently
コアとなるコードの解説
変更された行は、URL
型のコメント行です。
-
変更前:
// URL encapsulates a known safe URL as defined in RFC 3896.
このコメントは、
URL
型が「RFC 3896で定義された既知の安全なURL」をカプセル化すると説明していました。しかし、前述の通り、RFC 3896はURLの構文や安全性とは無関係なRFCでした。 -
変更後:
// URL encapsulates a known safe URL or URL substring (see RFC 3986).
この変更により、以下の2点が修正・追加されました。
- RFC参照の修正:
RFC 3896
がRFC 3986
に変更されました。これにより、URL
型が参照する標準が、URIの一般的な構文を定義する正しいRFCになりました。 - 「またはURLサブストリング」の追加:
URL
型が完全なURLだけでなく、URLの一部(サブストリング)も安全にカプセル化できることが明示されました。これは、html/template
がURLの様々な部分を文脈に応じてエスケープする際に、より柔軟に対応できることを示唆しています。例えば、パスやクエリパラメータなど、完全なURLではないがURLの一部として扱われるべき文字列もURL
型で表現できることを示しています。
- RFC参照の修正:
この変更は、コードの動作自体には影響を与えませんが、html/template
パッケージを使用する開発者にとって、URL
型の目的と適用範囲をより正確に理解するための重要なドキュメント修正です。特にセキュリティ関連の型においては、その定義が正確であることが、安全なアプリケーション開発に直結します。
関連リンク
- Go Issue 3528: https://github.com/golang/go/issues/3528
- Go CL 6493113: https://golang.org/cl/6493113
参考にした情報源リンク
- RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax: https://datatracker.ietf.org/doc/html/rfc3986
- RFC 3896 - Referrer Policy: https://datatracker.ietf.org/doc/html/rfc3896
- Go html/template package documentation: https://pkg.go.dev/html/template (このコミット時点のドキュメントではないが、一般的な情報源として)
- Cross-site scripting (XSS): https://developer.mozilla.org/ja/docs/Glossary/Cross-site_scripting
- Go html/template: Context-aware escaping for HTML templates: https://go.dev/blog/html-template (このコミット時点のブログではないが、
html/template
の背景を理解するのに役立つ)