[インデックス 12569] ファイルの概要
このコミットは、Go言語の標準ライブラリであるhtml/template
パッケージのドキュメント(doc.go
)における軽微な修正("doc nit")です。具体的には、Execute
メソッドに渡されるデータが、どのテンプレートパッケージ(text/template
またはhtml/template
)を使用しているかに関わらず、常に信頼できない(untrusted)ものであるというセキュリティ上の重要な前提をより明確にするための変更です。
コミット
commit 4084f0840126e7b271e651e2f3d955ea808c9645
Author: Russ Cox <rsc@golang.org>
Date: Mon Mar 12 14:26:10 2012 -0400
html/template: doc nit
Execute's data is untrusted regardless of package.
R=golang-dev, gri
CC=golang-dev
https://golang.org/cl/5797062
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/4084f0840126e7b271e651e2f3d955ea808c9645
元コミット内容
html/template
パッケージのドキュメントファイルsrc/pkg/html/template/doc.go
において、以下の変更が行われました。
--- a/src/pkg/html/template/doc.go
+++ b/src/pkg/html/template/doc.go
@@ -29,7 +29,7 @@ can be safely embedded in an HTML document. The escaping is contextual, so
actions can appear within JavaScript, CSS, and URI contexts.
The security model used by this package assumes that template authors are
-trusted, while text/template Execute\'s data parameter is not. More details are
+trusted, while Execute\'s data parameter is not. More details are
provided below.
Example
変更点は、doc.go
の29行目から30行目にかけての記述で、text/template
という具体的なパッケージ名が削除されたことです。
変更前: trusted, while text/template Execute's data parameter is not.
変更後: trusted, while Execute's data parameter is not.
変更の背景
この変更の背景には、Go言語のテンプレートパッケージにおけるセキュリティモデルの明確化があります。html/template
パッケージは、Webアプリケーションにおけるクロスサイトスクリプティング(XSS)などのインジェクション攻撃を防ぐために設計されています。このパッケージは、テンプレートに渡されるデータが信頼できないものであるという前提に立ち、自動的にエスケープ処理を行います。
元のドキュメントの記述「text/template Execute's data parameter is not.
」は、「text/template
パッケージのExecute
メソッドに渡されるデータは信頼できない」と読めるため、あたかもhtml/template
パッケージのExecute
メソッドに渡されるデータは信頼できるかのような誤解を与える可能性がありました。
しかし、実際にはhtml/template
パッケージを使用している場合でも、Execute
メソッドに渡されるデータは外部からの入力やデータベースからの取得など、アプリケーションの外部から来るものであるため、常に「信頼できない(untrusted)」ものとして扱う必要があります。html/template
は、その信頼できないデータを安全にHTMLに埋め込むためのエスケープ処理を提供するものであり、データの信頼性を保証するものではありません。
このコミットは、この重要なセキュリティ上の前提をより正確に、かつ普遍的に表現するために、「text/template
」という限定的な記述を削除し、「Execute
メソッドに渡されるデータは、どのパッケージを使用しているかに関わらず信頼できない」という意図を明確にすることを目的としています。
前提知識の解説
Go言語のテンプレートパッケージ (text/template
と html/template
)
Go言語には、テキストベースの出力を生成するためのtext/template
パッケージと、HTML出力を安全に生成するためのhtml/template
パッケージの2つの主要なテンプレートパッケージがあります。
-
text/template
: 汎用的なテキスト生成に使用されます。プレーンテキスト、設定ファイル、コード生成など、HTML以外のあらゆるテキスト形式に対応します。このパッケージは、渡されたデータを自動的にエスケープする機能を持たないため、Webアプリケーションでユーザー入力などを直接出力すると、XSSなどの脆弱性を引き起こす可能性があります。開発者が明示的にエスケープ処理を行う必要があります。 -
html/template
:text/template
をベースにしており、HTML、CSS、JavaScript、URIなどのコンテキストに応じて、自動的に適切なエスケープ処理を行うことで、XSS攻撃を防止します。このパッケージは、WebアプリケーションでHTMLを生成する際に推奨されます。
Execute
メソッド
両パッケージのTemplate
型には、テンプレートを実行して出力を生成するためのExecute
メソッドがあります。このメソッドは通常、io.Writer
と、テンプレートに渡すデータ(任意の型)を引数に取ります。
例:
tmpl, err := template.New("example").Parse("Hello, {{.}}!")
if err != nil {
log.Fatal(err)
}
err = tmpl.Execute(os.Stdout, "<script>alert('XSS')</script>")
if err != nil {
log.Fatal(err)
}
html/template
の場合、上記の例では<script>alert('XSS')</script>
が自動的にエスケープされ、安全なHTMLとして出力されます。
信頼できるデータと信頼できないデータ (Trusted vs. Untrusted Data)
Webセキュリティの文脈において、データは「信頼できる(trusted)」か「信頼できない(untrusted)」かに分類されます。
- 信頼できるデータ: アプリケーションの内部で生成され、その内容が完全に制御・検証されているデータ。例えば、アプリケーションの定数、内部ロジックで生成された数値など。
- 信頼できないデータ: ユーザーからの入力、外部APIからのレスポンス、データベースから取得したデータなど、アプリケーションの外部から供給され、その内容が完全に制御・検証されていないデータ。悪意のあるコードや不正なデータが含まれている可能性があります。
Webアプリケーション開発では、原則としてすべての入力は信頼できないものとして扱うのがセキュリティのベストプラクティスです。
クロスサイトスクリプティング (XSS)
XSSは、攻撃者がWebサイトに悪意のあるスクリプトを注入し、そのスクリプトが他のユーザーのブラウザで実行されることで発生するWebセキュリティの脆弱性です。これにより、セッションハイジャック、データの盗難、マルウェアの配布などが行われる可能性があります。html/template
のような自動エスケープ機能を持つテンプレートエンジンは、XSS攻撃を防ぐための重要な防御メカニズムです。
技術的詳細
このコミットは、Goのhtml/template
パッケージのセキュリティモデルに関するドキュメントの記述を改善するものです。
html/template
パッケージのセキュリティモデルは、以下の2つの主要な前提に基づいています。
- テンプレートの作者は信頼できる: テンプレートファイル自体(例:
.html
ファイル)は、開発者によって作成され、悪意のあるコードが含まれていないと見なされます。つまり、テンプレートの構造や静的な内容は安全であると仮定されます。 Execute
メソッドに渡されるデータは信頼できない: テンプレートに埋め込まれる動的なデータ(Execute
メソッドの第2引数)は、ユーザー入力、データベースからの取得、外部APIからのレスポンスなど、信頼できないソースから来る可能性があるため、常に悪意のある内容が含まれている可能性があると見なされます。
html/template
パッケージは、この「データは信頼できない」という前提に基づいて、テンプレート内のアクション({{.Var}}
など)で表示されるデータを、そのデータが埋め込まれるHTMLコンテキスト(例: HTML要素のテキストコンテンツ、属性値、JavaScriptコード、CSSプロパティ、URI)に応じて自動的にエスケープします。これにより、信頼できないデータが悪意のあるコードとして解釈されることを防ぎます。
元のドキュメントの記述「text/template Execute's data parameter is not.
」は、text/template
パッケージのExecute
メソッドに渡されるデータが信頼できないことを強調していました。これは事実ですが、この記述は「html/template
パッケージのExecute
メソッドに渡されるデータは信頼できる」という誤った解釈を招く可能性がありました。
このコミットによって、「text/template
」という限定的な表現が削除され、「Execute
メソッドに渡されるデータは(どのテンプレートパッケージを使用しているかに関わらず)信頼できない」という普遍的な真実が明確にされました。これは、開発者がhtml/template
を使用している場合でも、テンプレートに渡すデータの内容を常に疑い、適切なバリデーションやサニタイズをデータソース側で行うことの重要性を再確認させるものです。
たとえhtml/template
が自動エスケープを行うとしても、それはあくまで「安全なHTMLを生成する」ためのものであり、「データの信頼性を保証する」ものではありません。例えば、html/template
は、URLとして表示される文字列が有効なURLであるか、あるいはJavaScriptとして表示される文字列が有効なJavaScriptであるかまでは検証しません。それはアプリケーションロジックの責任です。このドキュメントの修正は、このセキュリティモデルのニュアンスをより正確に伝えるための重要な改善と言えます。
コアとなるコードの変更箇所
変更は、src/pkg/html/template/doc.go
ファイル内の1箇所のみです。
--- a/src/pkg/html/template/doc.go
+++ b/src/pkg/html/template/doc.go
@@ -29,7 +29,7 @@ can be safely embedded in an HTML document. The escaping is contextual, so
actions can appear within JavaScript, CSS, and URI contexts.
The security model used by this package assumes that template authors are
-trusted, while text/template Execute\'s data parameter is not. More details are
+trusted, while Execute\'s data parameter is not. More details are
provided below.
Example
具体的には、29行目のtext/template
という文字列が削除されました。
コアとなるコードの解説
この変更は、コードの動作に影響を与えるものではなく、純粋にドキュメントの記述を修正するものです。しかし、その修正が持つ意味は非常に重要です。
変更前:
The security model used by this package assumes that template authors are trusted, while text/template Execute's data parameter is not. More details are provided below.
変更後:
The security model used by this package assumes that template authors are trusted, while Execute's data parameter is not. More details are provided below.
「text/template
」という限定的な表現を削除することで、Execute
メソッドに渡されるデータが信頼できないという原則が、html/template
パッケージ自体にも適用されることを明確にしています。これは、html/template
が自動エスケープを行うからといって、開発者がデータソースの信頼性を考慮しなくてよいわけではない、というメッセージを強調しています。
この修正は、Goのテンプレートパッケージの設計思想、特にセキュリティに関する部分をより正確に反映しており、開発者が安全なWebアプリケーションを構築するための理解を深めるのに役立ちます。
関連リンク
- Go言語の
html/template
パッケージのドキュメント: https://pkg.go.dev/html/template - Go言語の
text/template
パッケージのドキュメント: https://pkg.go.dev/text/template - Go言語のGerrit Code Review: https://golang.org/cl/5797062
参考にした情報源リンク
- Go言語の公式ドキュメント
- Go言語のソースコードリポジトリ (GitHub)
- Webセキュリティに関する一般的な知識 (XSSなど)
- Gerrit Code Reviewシステムに関する情報
- Go言語のテンプレートに関するチュートリアルや解説記事 (一般的な知識として)
- Russ Cox氏のGo言語への貢献に関する情報 (一般的な知識として)