github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/html/template/doc.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 /* 6 パッケージテンプレート(html/template)は、コードインジェクションに対して安全なHTML出力を生成するための 7 データ駆動型テンプレートを実装します。それは [text/template] と同じインターフェースを提供し、出力がHTMLの場合は 8 [text/template] の代わりに使用すべきです。 9 10 ここでのドキュメンテーションは、パッケージのセキュリティ機能に焦点を当てています。 11 テンプレート自体のプログラミングについての情報は、[text/template] のドキュメンテーションを参照してください。 12 13 # Introduction 14 15 このパッケージは[text/template]をラップして、そのテンプレートAPIを共有して 16 HTMLテンプレートを安全に解析し実行できます。 17 18 tmpl, err := template.New("name").Parse(...) 19 // エラーチェックは省略 20 err = tmpl.Execute(out, data) 21 22 成功した場合、tmplは今後、インジェクションに対して安全になります。それ以外の場合、errはErrorCodeのドキュメントで定義されたエラーです。 23 24 HTMLテンプレートは、データ値をHTMLドキュメントに安全に埋め込むためにエンコードするべきプレーンテキストとして扱います。エスケープは文脈に依存するため、JavaScript、CSS、URIの文脈内にアクションが現れることがあります。 25 26 このパッケージが使用するセキュリティモデルは、テンプレートの作者が信頼できると仮定し、 27 一方でExecuteのデータパラメータは信頼できないと仮定します。詳細は以下に提供されています。 28 29 例 30 31 import "text/template" 32 ... 33 t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`) 34 err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>") 35 36 は以下を生成します 37 38 Hello, <script>alert('you have been pwned')</script>! 39 40 しかし、html/templateの文脈自動エスケープでは 41 42 import "html/template" 43 ... 44 t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`) 45 err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>") 46 47 は安全な、エスケープされたHTML出力を生成します 48 49 Hello, <script>alert('you have been pwned')</script>! 50 51 # Contexts 52 53 このパッケージはHTML、CSS、JavaScript、およびURIを理解します。それは各単純なアクションパイプラインに 54 サニタイジング関数を追加するので、以下の抜粋が与えられた場合 55 56 <a href="/search?q={{.}}">{{.}}</a> 57 58 パース時に、必要に応じてエスケープ関数を追加するため、各{{.}}が上書きされます。 59 この場合、それは次のようになります。 60 61 <a href="/search?q={{. | urlescaper | attrescaper}}">{{. | htmlescaper}}</a> 62 63 ここで、urlescaper、attrescaper、およびhtmlescaperは、内部エスケープ関数のエイリアスです。 64 65 これらの内部エスケープ関数については、アクションパイプラインがnilインターフェース値を評価すると、 66 それは空の文字列であるかのように扱われます。 67 68 # Namespaced and data- attributes 69 70 名前空間を持つ属性は、名前空間がないかのように扱われます。 71 以下の抜粋が与えられた場合 72 73 <a my:href="{{.}}"></a> 74 75 パース時に、属性はまるでそれがただの"href"であるかのように扱われます。 76 したがって、パース時にテンプレートは次のようになります: 77 78 <a my:href="{{. | urlescaper | attrescaper}}"></a> 79 80 同様に、"data-"プレフィックスを持つ属性は、まるでそれらが"data-"プレフィックスを持っていないかのように扱われます。したがって、以下が与えられた場合 81 82 <a data-href="{{.}}"></a> 83 84 パース時に、これは次のようになります。 85 86 <a data-href="{{. | urlescaper | attrescaper}}"></a> 87 88 属性が名前空間と"data-"プレフィックスの両方を持っている場合、コンテキストを決定するときには名前空間のみが削除されます。例えば 89 90 <a my:data-href="{{.}}"></a> 91 92 これは、"my:data-href"がただの"data-href"であるかのように、そして"href"であるかのように("data-"プレフィックスも無視される場合)扱われます。したがって、パース時には次のようになります。 93 94 <a my:data-href="{{. | attrescaper}}"></a> 95 96 特別なケースとして、"xmlns"名前空間を持つ属性は常にURLを含んでいるとして扱われます。以下の抜粋が与えられた場合 97 98 <a xmlns:title="{{.}}"></a> 99 <a xmlns:href="{{.}}"></a> 100 <a xmlns:onclick="{{.}}"></a> 101 102 パース時に、それらは次のようになります。 103 104 <a xmlns:title="{{. | urlescaper | attrescaper}}"></a> 105 <a xmlns:href="{{. | urlescaper | attrescaper}}"></a> 106 <a xmlns:onclick="{{. | urlescaper | attrescaper}}"></a> 107 108 # Errors 109 110 詳細はErrorCodeのドキュメンテーションを参照してください。 111 112 # A fuller picture 113 114 このパッケージのコメントの残りの部分は、最初の読み込み時にスキップしても構いません。これには、 115 エスケープの文脈とエラーメッセージを理解するために必要な詳細が含まれています。ほとんどのユーザーは 116 これらの詳細を理解する必要はありません。 117 118 # Contexts 119 120 {{.}}が`O'Reilly: How are <i>you</i>?`と仮定すると、以下の表は 121 左側の文脈で{{.}}がどのように表示されるかを示しています。 122 123 Context {{.}} After 124 {{.}} O'Reilly: How are <i>you</i>? 125 <a title='{{.}}'> O'Reilly: How are you? 126 <a href="/{{.}}"> O'Reilly: How are %3ci%3eyou%3c/i%3e? 127 <a href="?q={{.}}"> O'Reilly%3a%20How%20are%3ci%3e...%3f 128 <a onx='f("{{.}}")'> O\x27Reilly: How are \x3ci\x3eyou...? 129 <a onx='f({{.}})'> "O\x27Reilly: How are \x3ci\x3eyou...?" 130 <a onx='pattern = /{{.}}/;'> O\x27Reilly: How are \x3ci\x3eyou...\x3f 131 132 安全でないコンテキストで使用された場合、その値はフィルタリングされる可能性があります: 133 134 Context {{.}} After 135 <a href="{{.}}"> #ZgotmplZ 136 137 なぜなら "O'Reilly:" は "http:" のような許可されたプロトコルではないからです。 138 139 もし {{.}} が無害な単語、`left`であるなら、それはより広範に現れることができます。 140 141 Context {{.}} After 142 {{.}} left 143 <a title='{{.}}'> left 144 <a href='{{.}}'> left 145 <a href='/{{.}}'> left 146 <a href='?dir={{.}}'> left 147 <a style="border-{{.}}: 4px"> left 148 <a style="align: {{.}}"> left 149 <a style="background: '{{.}}'> left 150 <a style="background: url('{{.}}')> left 151 <style>p.{{.}} {color:red}</style> left 152 153 非文字列の値はJavaScriptの文脈で使用できます。 154 もし {{.}} が 155 156 struct{A,B string}{ "foo", "bar" } 157 158 エスケープされたテンプレート内で 159 160 <script>var pair = {{.}};</script> 161 162 その後、テンプレートの出力は次のようになります。 163 164 <script>var pair = {"A": "foo", "B": "bar"};</script> 165 166 JavaScriptの文脈で埋め込むために非文字列コンテンツがどのようにマーシャルされるかを理解するために、jsonパッケージを参照してください。 167 168 # Typed Strings 169 170 デフォルトでは、このパッケージはすべてのパイプラインがプレーンテキストの文字列を生成すると仮定します。 171 それは、そのプレーンテキスト文字列を適切な文脈で正しく安全に埋め込むために必要なエスケープパイプラインステージを追加します。 172 173 データ値がプレーンテキストでない場合、そのタイプでマークすることで、それが過度にエスケープされないようにすることができます。 174 175 Types HTML, JS, URL, and others from content.go can carry safe content that is 176 exempted from escaping. 177 178 テンプレート 179 180 Hello, {{.}}! 181 182 は以下のように呼び出すことができます 183 184 tmpl.Execute(out, template.HTML(`<b>World</b>`)) 185 186 これにより 187 188 Hello, <b>World</b>! 189 190 が生成されます。 191 192 これは、{{.}}が通常の文字列であった場合に生成される 193 194 Hello, <b>World<b>! 195 196 とは異なります。 197 198 # Security Model 199 200 https://rawgit.com/mikesamuel/sanitized-jquery-templates/trunk/safetemplate.html#problem_definition は、このパッケージが使用する「安全」を定義しています。 201 202 このパッケージは、テンプレートの作者が信頼できると仮定し、Executeのデータパラメータは信頼できないと仮定し、信頼できないデータに対して以下のプロパティを保持しようとします: 203 204 Structure Preservation Property: 205 "... テンプレートの作者が安全なテンプレート言語でHTMLタグを書くとき、 206 ブラウザは出力の対応する部分を、信頼できないデータの値に関係なくタグとして解釈します。 207 同様に、属性の境界やJSとCSSの文字列の境界などの他の構造についても同様です。" 208 209 Code Effect Property: 210 "... テンプレートの出力をページに注入する結果として実行されるのは、 211 テンプレートの作者によって指定されたコードのみであり、 212 同じ結果として実行されるすべてのコードもテンプレートの作者によって指定されるべきです。" 213 214 Least Surprise Property: 215 "HTML、CSS、JavaScriptに精通し、コンテキストに応じた自動エスケープが行われることを知っている開発者(またはコードレビュアー)は、{{.}}を見て、どのようなサニタイゼーションが行われるかを正しく推測することができるべきです。" 216 217 最小驚きの原則の結果として、ECMAScript 6のテンプレートリテラル内のテンプレートアクションはデフォルトで無効になっています。 218 これらのリテラル内での文字列補間の処理はかなり複雑で、それをサポートする明確な安全な方法がありません。 219 ECMAScript 6のテンプレートリテラル内でテンプレートアクションを再度有効にするには、GODEBUG=jstmpllitinterp=1環境変数を使用します。 220 */ 221 package template