Source file src/html/template/doc.go
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 Package template (html/template) implements data-driven templates for 7 generating HTML output safe against code injection. It provides the 8 same interface as [text/template] and should be used instead of 9 [text/template] whenever the output is HTML. 10 11 The documentation here focuses on the security features of the package. 12 For information about how to program the templates themselves, see the 13 documentation for [text/template]. 14 15 # Introduction 16 17 This package wraps [text/template] so you can share its template API 18 to parse and execute HTML templates safely. 19 20 tmpl, err := template.New("name").Parse(...) 21 // Error checking elided 22 err = tmpl.Execute(out, data) 23 24 If successful, tmpl will now be injection-safe. Otherwise, err is an error 25 defined in the docs for ErrorCode. 26 27 HTML templates treat data values as plain text which should be encoded so they 28 can be safely embedded in an HTML document. The escaping is contextual, so 29 actions can appear within JavaScript, CSS, and URI contexts. 30 31 Comments are stripped from output, except for those passed in via the 32 [HTML], [CSS], and [JS] types for their respective contexts. 33 34 The security model used by this package assumes that template authors are 35 trusted, while Execute's data parameter is not. More details are 36 provided below. 37 38 Example 39 40 import "text/template" 41 ... 42 t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`) 43 err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>") 44 45 produces 46 47 Hello, <script>alert('you have been pwned')</script>! 48 49 but the contextual autoescaping in html/template 50 51 import "html/template" 52 ... 53 t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`) 54 err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>") 55 56 produces safe, escaped HTML output 57 58 Hello, <script>alert('you have been pwned')</script>! 59 60 # Contexts 61 62 This package understands HTML, CSS, JavaScript, and URIs. It adds sanitizing 63 functions to each simple action pipeline, so given the excerpt 64 65 <a href="/search?q={{.}}">{{.}}</a> 66 67 At parse time each {{.}} is overwritten to add escaping functions as necessary. 68 In this case it becomes 69 70 <a href="/search?q={{. | urlescaper | attrescaper}}">{{. | htmlescaper}}</a> 71 72 where urlescaper, attrescaper, and htmlescaper are aliases for internal escaping 73 functions. 74 75 For these internal escaping functions, if an action pipeline evaluates to 76 a nil interface value, it is treated as though it were an empty string. 77 78 # Namespaced and data- attributes 79 80 Attributes with a namespace are treated as if they had no namespace. 81 Given the excerpt 82 83 <a my:href="{{.}}"></a> 84 85 At parse time the attribute will be treated as if it were just "href". 86 So at parse time the template becomes: 87 88 <a my:href="{{. | urlescaper | attrescaper}}"></a> 89 90 Similarly to attributes with namespaces, attributes with a "data-" prefix are 91 treated as if they had no "data-" prefix. So given 92 93 <a data-href="{{.}}"></a> 94 95 At parse time this becomes 96 97 <a data-href="{{. | urlescaper | attrescaper}}"></a> 98 99 If an attribute has both a namespace and a "data-" prefix, only the namespace 100 will be removed when determining the context. For example 101 102 <a my:data-href="{{.}}"></a> 103 104 This is handled as if "my:data-href" was just "data-href" and not "href" as 105 it would be if the "data-" prefix were to be ignored too. Thus at parse 106 time this becomes just 107 108 <a my:data-href="{{. | attrescaper}}"></a> 109 110 As a special case, attributes with the namespace "xmlns" are always treated 111 as containing URLs. Given the excerpts 112 113 <a xmlns:title="{{.}}"></a> 114 <a xmlns:href="{{.}}"></a> 115 <a xmlns:onclick="{{.}}"></a> 116 117 At parse time they become: 118 119 <a xmlns:title="{{. | urlescaper | attrescaper}}"></a> 120 <a xmlns:href="{{. | urlescaper | attrescaper}}"></a> 121 <a xmlns:onclick="{{. | urlescaper | attrescaper}}"></a> 122 123 # Errors 124 125 See the documentation of ErrorCode for details. 126 127 # A fuller picture 128 129 The rest of this package comment may be skipped on first reading; it includes 130 details necessary to understand escaping contexts and error messages. Most users 131 will not need to understand these details. 132 133 # Contexts 134 135 Assuming {{.}} is `O'Reilly: How are <i>you</i>?`, the table below shows 136 how {{.}} appears when used in the context to the left. 137 138 Context {{.}} After 139 {{.}} O'Reilly: How are <i>you</i>? 140 <a title='{{.}}'> O'Reilly: How are you? 141 <a href="/{{.}}"> O'Reilly: How are %3ci%3eyou%3c/i%3e? 142 <a href="?q={{.}}"> O'Reilly%3a%20How%20are%3ci%3e...%3f 143 <a onx='f("{{.}}")'> O\x27Reilly: How are \x3ci\x3eyou...? 144 <a onx='f({{.}})'> "O\x27Reilly: How are \x3ci\x3eyou...?" 145 <a onx='pattern = /{{.}}/;'> O\x27Reilly: How are \x3ci\x3eyou...\x3f 146 147 If used in an unsafe context, then the value might be filtered out: 148 149 Context {{.}} After 150 <a href="{{.}}"> #ZgotmplZ 151 152 since "O'Reilly:" is not an allowed protocol like "http:". 153 154 If {{.}} is the innocuous word, `left`, then it can appear more widely, 155 156 Context {{.}} After 157 {{.}} left 158 <a title='{{.}}'> left 159 <a href='{{.}}'> left 160 <a href='/{{.}}'> left 161 <a href='?dir={{.}}'> left 162 <a style="border-{{.}}: 4px"> left 163 <a style="align: {{.}}"> left 164 <a style="background: '{{.}}'> left 165 <a style="background: url('{{.}}')> left 166 <style>p.{{.}} {color:red}</style> left 167 168 Non-string values can be used in JavaScript contexts. 169 If {{.}} is 170 171 struct{A,B string}{ "foo", "bar" } 172 173 in the escaped template 174 175 <script>var pair = {{.}};</script> 176 177 then the template output is 178 179 <script>var pair = {"A": "foo", "B": "bar"};</script> 180 181 See package json to understand how non-string content is marshaled for 182 embedding in JavaScript contexts. 183 184 # Typed Strings 185 186 By default, this package assumes that all pipelines produce a plain text string. 187 It adds escaping pipeline stages necessary to correctly and safely embed that 188 plain text string in the appropriate context. 189 190 When a data value is not plain text, you can make sure it is not over-escaped 191 by marking it with its type. 192 193 Types HTML, JS, URL, and others from content.go can carry safe content that is 194 exempted from escaping. 195 196 The template 197 198 Hello, {{.}}! 199 200 can be invoked with 201 202 tmpl.Execute(out, template.HTML(`<b>World</b>`)) 203 204 to produce 205 206 Hello, <b>World</b>! 207 208 instead of the 209 210 Hello, <b>World<b>! 211 212 that would have been produced if {{.}} was a regular string. 213 214 # Security Model 215 216 https://web.archive.org/web/20160501113828/http://js-quasis-libraries-and-repl.googlecode.com/svn/trunk/safetemplate.html#problem_definition defines "safe" as used by this package. 217 218 This package assumes that template authors are trusted, that Execute's data 219 parameter is not, and seeks to preserve the properties below in the face 220 of untrusted data: 221 222 Structure Preservation Property: 223 "... when a template author writes an HTML tag in a safe templating language, 224 the browser will interpret the corresponding portion of the output as a tag 225 regardless of the values of untrusted data, and similarly for other structures 226 such as attribute boundaries and JS and CSS string boundaries." 227 228 Code Effect Property: 229 "... only code specified by the template author should run as a result of 230 injecting the template output into a page and all code specified by the 231 template author should run as a result of the same." 232 233 Least Surprise Property: 234 "A developer (or code reviewer) familiar with HTML, CSS, and JavaScript, who 235 knows that contextual autoescaping happens should be able to look at a {{.}} 236 and correctly infer what sanitization happens." 237 238 Previously, ECMAScript 6 template literal were disabled by default, and could be 239 enabled with the GODEBUG=jstmpllitinterp=1 environment variable. Template 240 literals are now supported by default, and setting jstmpllitinterp has no 241 effect. 242 */ 243 package template 244