Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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/templatehtml/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エンティティ(例: &lt;, &gt;, &amp;, &quot;, &#39;)に変換することです。

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が自動的にエスケープ処理を行うこと、特に>のような文字を&amp;gt;に変換することで、ユーザーデータがHTMLフォームを破壊するのを防ぐことを強調しています。これは、|htmlパイプが不要であることの根拠を明確にするものです。

コアとなるコードの変更箇所

このコミットでは、以下の3つのファイルが変更されています。

  1. doc/articles/wiki/edit.html
  2. doc/articles/wiki/index.html
  3. 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>&gt;</code> with <code>&amp;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>&gt;</code>), replacing it\n+with <code>&amp;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が生成されることを保証する。例えば、>&amp;gt;に自動的にエスケープし、ユーザーデータがフォームHTMLを破壊しないようにする」という説明に変わっています。

    この変更は、html/templateの自動エスケープがデフォルトの動作であり、開発者が明示的に|htmlパイプを使用する必要がないことを強調しています。これにより、読者はhtml/templateのセキュリティ上の利点をより正確に理解し、安全なWebアプリケーションを開発するための正しい知識を得ることができます。

これらの変更は、Goのhtml/templateパッケージの設計思想と、Webセキュリティにおけるその役割をより正確に反映するための重要なドキュメント改善です。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (html/template および text/template パッケージ)
  • クロスサイトスクリプティング (XSS) に関する一般的なWebセキュリティ情報
  • Go言語のコミット履歴とIssueトラッカー
  • Go html/template - The Go Programming Language (このコミットで更新された記事の現在のバージョン)