[インデックス 12972] ファイルの概要
このコミットは、Go言語の公式ドキュメント内にあるWiki記事のテンプレートが、html/template
パッケージをより適切に使用するように更新されたものです。具体的には、html/template
が提供する自動エスケープ機能の利用方法を修正し、それに関する説明を改善しています。これにより、クロスサイトスクリプティング(XSS)攻撃に対するセキュリティが強化され、テンプレートの記述がより簡潔になります。
コミット
commit 4d3db77c6906d09038e55915653dc98cdf4d66bb
Author: David Symonds <dsymonds@golang.org>
Date: Thu Apr 26 17:50:44 2012 +1000
doc: update wiki article to use html/template properly.
Fixes #3569.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/6116055
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/4d3db77c6906d09038e55915653dc98cdf4d66bb
元コミット内容
doc: update wiki article to use html/template properly.
Fixes #3569.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/6116055
変更の背景
この変更は、Go言語のIssue #3569に対応するものです。Issue #3569は、html/template
パッケージのドキュメントと使用例が、その自動エスケープ機能を正しく反映していないという問題提起でした。
Goのhtml/template
パッケージは、Webアプリケーションにおけるセキュリティ上の脆弱性、特にクロスサイトスクリプティング(XSS)攻撃を防ぐために設計されています。このパッケージは、テンプレートに挿入されるデータがHTMLコンテキストで安全に表示されるように、自動的にエスケープ処理を行います。しかし、初期のドキュメントやサンプルコードでは、この自動エスケープ機能が十分に理解されておらず、開発者が手動で|html
パイプを使用してエスケープ処理を適用しているケースが見られました。
このコミットの目的は、ドキュメント内のWiki記事を修正し、html/template
の自動エスケープ機能がデフォルトで有効であり、明示的な|html
パイプが不要であることを明確にすることです。これにより、開発者がより安全で簡潔なテンプレートコードを書けるようになります。
前提知識の解説
1. Go言語のテンプレートパッケージ (text/template
と html/template
)
Go言語には、テキストベースの出力を生成するためのtext/template
パッケージと、HTML出力を安全に生成するためのhtml/template
パッケージの2種類が標準で提供されています。
text/template
: 任意のテキスト形式の出力を生成するために使用されます。エスケープ処理は自動で行われないため、セキュリティを考慮する必要がある場合は、開発者が明示的にエスケープ処理を実装する必要があります。html/template
: HTML出力を生成するために特化しており、クロスサイトスクリプティング(XSS)攻撃を防ぐための自動エスケープ機能が組み込まれています。このパッケージは、テンプレートに挿入されるデータがHTML、URL、JavaScriptなどのコンテキストで安全になるように、適切なエスケープ処理を自動的に適用します。
2. クロスサイトスクリプティング (XSS)
XSSは、Webアプリケーションのセキュリティ脆弱性の一種です。攻撃者は、悪意のあるスクリプト(通常はJavaScript)をWebページに挿入し、そのページを閲覧したユーザーのブラウザで実行させます。これにより、セッションハイジャック、個人情報の窃取、Webサイトの改ざんなど、様々な被害が発生する可能性があります。
XSS攻撃を防ぐためには、ユーザーからの入力や外部から取得したデータをHTML出力に含める際に、適切なエスケープ処理を施すことが不可欠です。エスケープ処理とは、HTMLの特殊文字(例: <
, >
, &
, "
, '
)を、ブラウザがそれらをHTMLタグや属性として解釈しないように、対応するHTMLエンティティ(例: <
, >
, &
, "
, '
)に変換することです。
3. テンプレートにおけるパイプ (|
)
Goのテンプレート構文では、パイプ記号 (|
) を使用して、値に関数を適用することができます。例えば、{{.Title |html}}
という記述は、.Title
の値に対してhtml
という関数(またはフィルタ)を適用し、その結果を出力することを意味します。
このコミット以前のhtml/template
の使用例では、自動エスケープ機能があるにもかかわらず、明示的に|html
パイプを使用している箇所が見られました。これは、html/template
の自動エスケープの仕組みが十分に理解されていなかったためと考えられます。
技術的詳細
html/template
パッケージの核心的な機能は、そのコンテキストアウェアな自動エスケープです。これは、テンプレートエンジンが、出力されるデータがHTMLドキュメントのどの部分(例: HTML要素のコンテンツ、属性値、JavaScriptコード、URL)に挿入されるかを認識し、そのコンテキストに最適なエスケープ処理を自動的に適用するという意味です。
例えば、<div>{{.Content}}</div>
のようにHTML要素の内部にデータを挿入する場合、html/template
は自動的にHTMLエスケープを行います。また、<a href="{{.URL}}">
のようにURLとしてデータを挿入する場合、URLエンコードを適用します。これにより、開発者は手動でエスケープ処理を記述する手間が省け、同時にXSS脆弱性のリスクを大幅に低減できます。
この自動エスケープ機能があるため、html/template
を使用する際には、通常、明示的に|html
パイプを使用する必要はありません。むしろ、|html
パイプは、text/template
でHTMLエスケープを明示的に行いたい場合や、html/template
で特定のコンテキストでのエスケープを上書きしたい場合にのみ使用されるべきです。しかし、後者の用途は非常に稀であり、通常はhtml/template
の自動処理に任せるのが最善です。
このコミットでは、既存のWiki記事のテンプレートから冗長な|html
パイプを削除することで、html/template
の正しい使用方法を示しています。これにより、テンプレートコードがよりクリーンになり、html/template
の自動エスケープ機能への依存が明確になります。
また、doc/articles/wiki/index.html
のドキュメント更新では、html/template
が自動的にエスケープ処理を行うこと、特に>
のような文字を&gt;
に変換することで、ユーザーデータがHTMLフォームを破壊するのを防ぐことを強調しています。これは、|html
パイプが不要であることの根拠を明確にするものです。
コアとなるコードの変更箇所
このコミットでは、以下の3つのファイルが変更されています。
doc/articles/wiki/edit.html
doc/articles/wiki/index.html
doc/articles/wiki/view.html
doc/articles/wiki/edit.html
の変更点
--- a/doc/articles/wiki/edit.html
+++ b/doc/articles/wiki/edit.html
@@ -1,6 +1,6 @@
-<h1>Editing {{.Title |html}}</h1>
+<h1>Editing {{.Title}}</h1>
-<form action="/save/{{.Title |html}}" method="POST">
-<div><textarea name="body" rows="20" cols="80">{{printf "%s" .Body |html}}</textarea></div>
+<form action="/save/{{.Title}}" method="POST">
+<div><textarea name="body" rows="20" cols="80">{{printf "%s" .Body}}</textarea></div>
<div><input type="submit" value="Save"></div>
</form>
doc/articles/wiki/index.html
の変更点
--- a/doc/articles/wiki/index.html
+++ b/doc/articles/wiki/index.html
@@ -359,10 +359,10 @@ First, we must add <code>html/template</code> to the list of imports:
<pre>
import (
+ <b>"html/template"</b>
"http"
"io/ioutil"
"os"
- <b>"html/template"</b>
)
</pre>
@@ -397,10 +397,11 @@ Template directives are enclosed in double curly braces.\n The <code>printf "%s" .Body</code> instruction is a function call\n that outputs <code>.Body</code> as a string instead of a stream of bytes,\n the same as a call to <code>fmt.Printf</code>.\n-The <code>|html</code> part of each directive pipes the value through the\n-<code>html</code> formatter before outputting it, which escapes HTML\n-characters (such as replacing <code>></code> with <code>&gt;</code>),\n-preventing user data from corrupting the form HTML. \n+The <code>html/template</code> package helps guarantee that only safe and\n+correct-looking HTML is generated by template actions. For instance, it\n+automatically escapes any greater than sign (<code>></code>), replacing it\n+with <code>&gt;</code>, to make sure user data does not corrupt the form\n+HTML.\n </p>
<p>
doc/articles/wiki/view.html
の変更点
--- a/doc/articles/wiki/view.html
+++ b/doc/articles/wiki/view.html
@@ -1,5 +1,5 @@
-<h1>{{.Title |html}}</h1>
+<h1>{{.Title}}</h1>
-<p>[<a href="/edit/{{.Title |html}}">edit</a>]</p>
+<p>[<a href="/edit/{{.Title}}">edit</a>]</p>
-<div>{{printf "%s" .Body |html}}</div>
+<div>{{printf "%s" .Body}}</div>
コアとなるコードの解説
1. edit.html
および view.html
からの |html
パイプの削除
これらのファイルでは、{{.Title |html}}
や {{printf "%s" .Body |html}}
のように、テンプレート変数に明示的に|html
パイプを適用していた箇所が、{{.Title}}
や {{printf "%s" .Body}}
のように削除されています。
これは、html/template
パッケージがデフォルトでコンテキストアウェアな自動エスケープを行うため、これらのパイプが冗長であるだけでなく、誤解を招く可能性があったためです。html/template
は、変数が挿入されるHTMLのコンテキスト(例: <h1>
タグ内、action
属性内、textarea
内)を自動的に判断し、適切なエスケープ処理を適用します。したがって、開発者が手動で|html
を指定する必要はありません。この変更により、テンプレートコードがより簡潔になり、html/template
の意図された使用方法が明確になります。
2. index.html
のドキュメント更新
index.html
は、GoのWikiアプリケーションの作成方法を説明するドキュメントです。このファイルでは、主に以下の2つの変更が行われています。
-
import "html/template"
の位置変更:import
ブロック内で"html/template"
の記述が移動されています。これは機能的な変更ではなく、単にインポートの順序を整理したものです。 -
html/template
の自動エスケープに関する説明の更新: 最も重要な変更は、html/template
の自動エスケープ機能に関する説明文が修正された点です。変更前は、「|html
パイプが値をhtml
フォーマッタに通し、HTML文字をエスケープする」という説明がありましたが、変更後は、「html/template
パッケージは、テンプレートアクションによって安全で正しいHTMLが生成されることを保証する。例えば、>
を&gt;
に自動的にエスケープし、ユーザーデータがフォームHTMLを破壊しないようにする」という説明に変わっています。この変更は、
html/template
の自動エスケープがデフォルトの動作であり、開発者が明示的に|html
パイプを使用する必要がないことを強調しています。これにより、読者はhtml/template
のセキュリティ上の利点をより正確に理解し、安全なWebアプリケーションを開発するための正しい知識を得ることができます。
これらの変更は、Goのhtml/template
パッケージの設計思想と、Webセキュリティにおけるその役割をより正確に反映するための重要なドキュメント改善です。
関連リンク
- Go Issue #3569: https://github.com/golang/go/issues/3569
- Go
html/template
パッケージのドキュメント: https://pkg.go.dev/html/template (現在の最新ドキュメント) - Go
text/template
パッケージのドキュメント: https://pkg.go.dev/text/template
参考にした情報源リンク
- Go言語の公式ドキュメント (
html/template
およびtext/template
パッケージ) - クロスサイトスクリプティング (XSS) に関する一般的なWebセキュリティ情報
- Go言語のコミット履歴とIssueトラッカー
- Go html/template - The Go Programming Language (このコミットで更新された記事の現在のバージョン)