[インデックス 19675] ファイルの概要
コミット
commit a31eeef7fff2a08306c622b8d16f1697b86eb249
Author: Josh Bleecher Snyder <josharian@gmail.com>
Date: Mon Jul 7 17:10:33 2014 -0700
undo CL 101670044 / 49a6cbd80cf2
Broke build; missing deps_test change. Will re-send the original with the appropriate fix.
««« original CL description
net/rpc: use html/template to render html
Found using the vet check in CL 106370045.
LGTM=r
R=golang-codereviews, r
CC=golang-codereviews
https://golang.org/cl/101670044
»»»
TBR=r
CC=golang-codereviews
https://golang.org/cl/110880044
---
src/pkg/net/rpc/debug.go | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n
diff --git a/src/pkg/net/rpc/debug.go b/src/pkg/net/rpc/debug.go
index 98b2c1c6c4..926466d625 100644
--- a/src/pkg/net/rpc/debug.go
+++ b/src/pkg/net/rpc/debug.go
@@ -11,9 +11,9 @@ package rpc
import (
"fmt"
-" html/template"
"net/http"
"sort"
+" text/template"
)
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/a31eeef7fff2a08306c622b8d16f1697b86eb249
元コミット内容
このコミットは、以前の変更 (Change List: CL 101670044 / コミットハッシュ: 49a6cbd80cf2) を元に戻す (undo) ものであり、その元の変更内容は以下の通りです。
「net/rpc: HTMLをレンダリングするためにhtml/templateを使用する」
この変更は、CL 106370045 で導入された vet ツールによるチェックで見つかった問題に対応するためのものでした。
変更の背景
このコミット a31eeef7fff2a08306c622b8d16f1697b86eb249 は、以前のコミット 49a6cbd80cf2 (CL 101670044) を元に戻すために作成されました。元のコミットは、net/rpc パッケージ内のデバッグ用HTMLレンダリングにおいて、text/template の代わりに html/template を使用するように変更することを目的としていました。これは、Goの vet ツールによって検出された潜在的なセキュリティ問題(HTMLエスケープの欠如)に対処するためでした。
しかし、この変更はビルドを壊してしまいました。コミットメッセージによると、「Broke build; missing deps_test change.」とあり、これはテストの依存関係の変更が不足していたことが原因でビルドが失敗したことを示しています。ビルドが壊れた状態では開発が継続できないため、一時的に元の状態に戻し、適切な修正(不足していた deps_test の変更)を加えてから再度元の変更を送信する計画でした。
前提知識の解説
Go言語の net/rpc パッケージ
net/rpc パッケージは、Go言語でリモートプロシージャコール (RPC) を実装するための標準ライブラリです。RPCは、異なるアドレス空間(通常はネットワーク上の別のコンピュータ)にあるプログラムのプロシージャ(関数やメソッド)を、あたかもローカルな呼び出しであるかのように実行できるようにするメカニズムです。
- 目的: 分散システムが通信できるようにし、オブジェクトのエクスポートされたメソッドをリモートから利用可能にします。
- 動作原理:
- サーバー: サービスとして利用可能にするために、オブジェクトを登録します。通常、
ServeConnで単一の接続を処理するか、AcceptまたはHandleHTTPでHTTP接続用のネットワークリスナーを設定します。 - クライアント: RPCサーバーへの接続を確立し、
NewClientまたはDial(HTTPの場合はDialHTTP) を使用してサービスと対話します。その後、Call(同期) またはGo(非同期) を使用してリモートメソッドを呼び出します。
- サーバー: サービスとして利用可能にするために、オブジェクトを登録します。通常、
- メソッドの要件:
net/rpcを介して公開されるメソッドは、特定のエクスポートルール、引数の型、およびエラーの戻り値の型を満たす必要があります。 - データエンコーディング: デフォルトでは、Goの
encoding/gobパッケージを使用してデータをシリアライズします。これはGo間の通信には効率的ですが、他の言語との互換性はありません。 - 現状:
net/rpcパッケージは「凍結」されており、新しい機能は追加されていません。
Go言語のテンプレートパッケージ: html/template と text/template
Go言語には、テンプレートを扱うための2つの主要なパッケージがあります。これらは構文とインターフェースを共有していますが、その目的とセキュリティ機能において重要な違いがあります。
-
text/template:- 目的: プレーンテキストの出力を生成するために設計されています。
- セキュリティ: データに対して自動的なエスケープやサニタイズを行いません。
- 使用例: HTMLではない出力(例: メール、設定ファイル、コマンドラインツールの出力、テキストベースのレポートなど)の生成に適しています。
-
html/template:- 目的: HTML出力を生成するために特別に設計されています。
- セキュリティ: 最も重要な機能は、自動的なコンテキストに応じたエスケープです。これにより、クロスサイトスクリプティング (XSS) 攻撃のようなコードインジェクションの脆弱性を防ぐためにデータをサニタイズします。データが挿入されるコンテキスト(HTML要素内、属性内、JavaScript、CSSなど)を理解し、適切なエスケープルールを適用します。
- 使用例: ユーザー入力のような信頼できないソースからのデータを含むHTMLコンテンツを生成する際には、常に
html/templateを使用すべきです。 template.HTML型: このパッケージはtemplate.HTMLのような型を提供し、エスケープすべきではない「安全な」HTMLとしてコンテンツをマークできます。しかし、信頼できない入力でこの型を使用すると、XSS脆弱性を再導入する可能性があるため、信頼できるソースからの安全なコンテンツにのみ使用すべきです。
要するに、両パッケージは強力なテンプレート機能を提供しますが、html/template は一般的なWeb脆弱性に対する組み込みの保護があるため、WebアプリケーションでHTMLを生成する際の安全な選択肢であり、推奨されるパッケージです。
Go言語の vet ツール
vet ツールは、Goのソースコードを静的に分析し、疑わしい構成要素や潜在的なエラーを報告するツールです。例えば、printf フォーマット文字列の誤用、構造体タグの誤り、そしてこのケースのように、HTMLを生成する際に text/template を使用していることなどを検出できます。vet はGoのビルドプロセスやCI/CDパイプラインに組み込まれることが多く、コード品質とセキュリティの向上に貢献します。
技術的詳細
元のコミット 49a6cbd80cf2 は、net/rpc パッケージのデバッグインターフェースが提供するHTMLページをレンダリングする際に、text/template パッケージを使用していることに対する修正でした。text/template は汎用的なテキスト生成には適していますが、HTMLのような構造化されたマークアップを生成する際には、ユーザー入力などの動的なコンテンツを適切にエスケープしないため、クロスサイトスクリプティング (XSS) などのセキュリティ脆弱性を引き起こす可能性があります。
html/template パッケージは、このセキュリティ上の懸念を解決するために設計されています。これは、テンプレートに渡されるデータがHTMLコンテキスト内で安全にレンダリングされるように、自動的にコンテキストに応じたエスケープを行います。これにより、悪意のあるスクリプトがページに挿入されるのを防ぎます。
元のコミットは、vet ツールが net/rpc/debug.go 内で text/template の不適切な使用を検出したことを受けて行われました。これは、vet ツールがGoコードベースの品質とセキュリティを維持する上で重要な役割を果たしていることを示しています。
しかし、この変更は「Broke build; missing deps_test change.」という問題を引き起こしました。これは、Goのビルドシステムが、変更されたコードが依存するテストファイルやビルド設定の更新を必要としていたにもかかわらず、それが提供されなかったことを意味します。Goのモジュールシステムやビルドプロセスでは、新しい依存関係が追加されたり、既存の依存関係が変更されたりした場合、それに応じて go.mod や go.sum ファイル、あるいは特定のテスト設定ファイル(この場合は deps_test と言及されている)を更新する必要があります。これが不足していたため、ビルドが失敗し、開発ワークフローが中断されました。
このコミット a31eeef7fff2a08306c622b8d16f1697b86eb249 は、ビルドを修正するために、一時的に html/template への切り替えを元に戻し、text/template に戻すことを決定しました。これは、機能の正確性やセキュリティよりも、ビルドの安定性を優先した一時的な措置です。コミットメッセージには「Will re-send the original with the appropriate fix.」と明記されており、これは適切な依存関係の修正を含めて、後で html/template への切り替えを再試行する意図があったことを示しています。
コアとなるコードの変更箇所
変更は src/pkg/net/rpc/debug.go ファイルのインポートセクションにあります。
--- a/src/pkg/net/rpc/debug.go
+++ b/src/pkg/net/rpc/debug.go
@@ -11,9 +11,9 @@ package rpc
import (
"fmt"
-" html/template"
"net/http"
"sort"
+" text/template"
)
具体的には、以下の変更が行われました。
- "html/template":html/templateパッケージのインポートが削除されました。+ "text/template":text/templateパッケージのインポートが追加されました。
コアとなるコードの解説
このコミットのコアとなるコード変更は、src/pkg/net/rpc/debug.go ファイルにおけるテンプレートパッケージのインポートの切り替えです。
元のコミット 49a6cbd80cf2 では、net/rpc のデバッグページでHTMLを安全にレンダリングするために、text/template から html/template への移行を試みました。しかし、この変更がビルドエラーを引き起こしたため、このコミット a31eeef7fff2a08306c622b8d16f1697b86eb249 ではその変更を元に戻しています。
具体的には、html/template のインポートを削除し、代わりに text/template のインポートを復活させています。これにより、net/rpc/debug.go 内のテンプレート関連のコードは、再び text/template パッケージの機能を使用するようになります。これは、ビルドを安定させるための一時的なロールバックであり、セキュリティ上の懸念を完全に解決するものではありません。コミットメッセージが示唆するように、この問題は後で適切な依存関係の修正を伴って再提出される予定でした。
関連リンク
- このコミットのGitHubページ: https://github.com/golang/go/commit/a31eeef7fff2a08306c622b8d16f1697b86eb249
- 元に戻された元の変更 (CL 101670044): https://golang.org/cl/101670044
- この元に戻す変更 (CL 110880044): https://golang.org/cl/110880044
参考にした情報源リンク
- Go言語
text/templateパッケージ公式ドキュメント: https://pkg.go.dev/text/template - Go言語
html/templateパッケージ公式ドキュメント: https://pkg.go.dev/html/template - Go言語
net/rpcパッケージ公式ドキュメント: https://pkg.go.dev/net/rpc - Go言語
vetツールに関する情報 (Go公式ブログなど): https://go.dev/blog/go-vet (一般的なgo vetの情報源として) html/templateとtext/templateの違いに関する解説記事 (例: DigitalOcean, Mediumなど):