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, &lt;script&gt;alert(&#39;you have been pwned&#39;)&lt;/script&gt;!
    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 &lt;i&gt;you&lt;/i&gt;?
   125  	<a title='{{.}}'>                O&#39;Reilly: How are you?
   126  	<a href="/{{.}}">                O&#39;Reilly: How are %3ci%3eyou%3c/i%3e?
   127  	<a href="?q={{.}}">              O&#39;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, &lt;b&gt;World&lt;b&gt;!
   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