| 1 |
747 |
jeremybenn |
// 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) is a specialization of package text/template
|
| 7 |
|
|
that automates the construction of HTML output that is safe against code
|
| 8 |
|
|
injection.
|
| 9 |
|
|
|
| 10 |
|
|
|
| 11 |
|
|
Introduction
|
| 12 |
|
|
|
| 13 |
|
|
This package wraps package template so you can use the standard template API
|
| 14 |
|
|
to parse and execute templates.
|
| 15 |
|
|
|
| 16 |
|
|
set, err := new(template.Set).Parse(...)
|
| 17 |
|
|
// Error checking elided
|
| 18 |
|
|
err = set.Execute(out, "Foo", data)
|
| 19 |
|
|
|
| 20 |
|
|
If successful, set will now be injection-safe. Otherwise, err is an error
|
| 21 |
|
|
defined in the docs for ErrorCode.
|
| 22 |
|
|
|
| 23 |
|
|
HTML templates treat data values as plain text which should be encoded so they
|
| 24 |
|
|
can be safely embedded in an HTML document. The escaping is contextual, so
|
| 25 |
|
|
actions can appear within JavaScript, CSS, and URI contexts.
|
| 26 |
|
|
|
| 27 |
|
|
The security model used by this package assumes that template authors are
|
| 28 |
|
|
trusted, while Execute's data parameter is not. More details are provided below.
|
| 29 |
|
|
|
| 30 |
|
|
Example
|
| 31 |
|
|
|
| 32 |
|
|
import "text/template"
|
| 33 |
|
|
...
|
| 34 |
|
|
t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
|
| 35 |
|
|
err = t.ExecuteTemplate(out, "T", "")
|
| 36 |
|
|
|
| 37 |
|
|
produces
|
| 38 |
|
|
|
| 39 |
|
|
Hello, !
|
| 40 |
|
|
|
| 41 |
|
|
but with contextual autoescaping,
|
| 42 |
|
|
|
| 43 |
|
|
import "html/template"
|
| 44 |
|
|
...
|
| 45 |
|
|
t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
|
| 46 |
|
|
err = t.ExecuteTemplate(out, "T", "")
|
| 47 |
|
|
|
| 48 |
|
|
produces safe, escaped HTML output
|
| 49 |
|
|
|
| 50 |
|
|
Hello, <script>alert('you have been pwned')</script>!
|
| 51 |
|
|
|
| 52 |
|
|
|
| 53 |
|
|
Contexts
|
| 54 |
|
|
|
| 55 |
|
|
This package understands HTML, CSS, JavaScript, and URIs. It adds sanitizing
|
| 56 |
|
|
functions to each simple action pipeline, so given the excerpt
|
| 57 |
|
|
|
| 58 |
|
|
{{.}}
|
| 59 |
|
|
|
| 60 |
|
|
At parse time each {{.}} is overwritten to add escaping functions as necessary.
|
| 61 |
|
|
In this case it becomes
|
| 62 |
|
|
|
| 63 |
|
|
{{. | html}}
|
| 64 |
|
|
|
| 65 |
|
|
|
| 66 |
|
|
Errors
|
| 67 |
|
|
|
| 68 |
|
|
See the documentation of ErrorCode for details.
|
| 69 |
|
|
|
| 70 |
|
|
|
| 71 |
|
|
A fuller picture
|
| 72 |
|
|
|
| 73 |
|
|
The rest of this package comment may be skipped on first reading; it includes
|
| 74 |
|
|
details necessary to understand escaping contexts and error messages. Most users
|
| 75 |
|
|
will not need to understand these details.
|
| 76 |
|
|
|
| 77 |
|
|
|
| 78 |
|
|
Contexts
|
| 79 |
|
|
|
| 80 |
|
|
Assuming {{.}} is `O'Reilly: How are you?`, the table below shows
|
| 81 |
|
|
how {{.}} appears when used in the context to the left.
|
| 82 |
|
|
|
| 83 |
|
|
Context {{.}} After
|
| 84 |
|
|
{{.}} O'Reilly: How are <i>you</i>?
|
| 85 |
|
|
O'Reilly: How are you?
|
| 86 |
|
|
O'Reilly: How are %3ci%3eyou%3c/i%3e?
|
| 87 |
|
|
O'Reilly%3a%20How%20are%3ci%3e...%3f
|
| 88 |
|
|
O\x27Reilly: How are \x3ci\x3eyou...?
|
| 89 |
|
|
"O\x27Reilly: How are \x3ci\x3eyou...?"
|
| 90 |
|
|
O\x27Reilly: How are \x3ci\x3eyou...\x3f
|
| 91 |
|
|
|
| 92 |
|
|
If used in an unsafe context, then the value might be filtered out:
|
| 93 |
|
|
|
| 94 |
|
|
Context {{.}} After
|
| 95 |
|
|
#ZgotmplZ
|
| 96 |
|
|
|
| 97 |
|
|
since "O'Reilly:" is not an allowed protocol like "http:".
|
| 98 |
|
|
|
| 99 |
|
|
|
| 100 |
|
|
If {{.}} is the innocuous word, `left`, then it can appear more widely,
|
| 101 |
|
|
|
| 102 |
|
|
Context {{.}} After
|
| 103 |
|
|
{{.}} left
|
| 104 |
|
|
left
|
| 105 |
|
|
left
|
| 106 |
|
|
left
|
| 107 |
|
|
left
|
| 108 |
|
|
left
|
| 109 |
|
|
left
|
| 110 |
|
|
| 111 |
|
|
| 112 |
|
|
left
|
|
|
| 113 |
|
|
|
| 114 |
|
|
Non-string values can be used in JavaScript contexts.
|
| 115 |
|
|
If {{.}} is
|
| 116 |
|
|
|
| 117 |
|
|
[]struct{A,B string}{ "foo", "bar" }
|
| 118 |
|
|
|
| 119 |
|
|
in the escaped template
|
| 120 |
|
|
|
| 121 |
|
|
|
| 122 |
|
|
|
| 123 |
|
|
then the template output is
|
| 124 |
|
|
|
| 125 |
|
|
|
| 126 |
|
|
|
| 127 |
|
|
See package json to understand how non-string content is marshalled for
|
| 128 |
|
|
embedding in JavaScript contexts.
|
| 129 |
|
|
|
| 130 |
|
|
|
| 131 |
|
|
Typed Strings
|
| 132 |
|
|
|
| 133 |
|
|
By default, this package assumes that all pipelines produce a plain text string.
|
| 134 |
|
|
It adds escaping pipeline stages necessary to correctly and safely embed that
|
| 135 |
|
|
plain text string in the appropriate context.
|
| 136 |
|
|
|
| 137 |
|
|
When a data value is not plain text, you can make sure it is not over-escaped
|
| 138 |
|
|
by marking it with its type.
|
| 139 |
|
|
|
| 140 |
|
|
Types HTML, JS, URL, and others from content.go can carry safe content that is
|
| 141 |
|
|
exempted from escaping.
|
| 142 |
|
|
|
| 143 |
|
|
The template
|
| 144 |
|
|
|
| 145 |
|
|
Hello, {{.}}!
|
| 146 |
|
|
|
| 147 |
|
|
can be invoked with
|
| 148 |
|
|
|
| 149 |
|
|
tmpl.Execute(out, HTML(`World`))
|
| 150 |
|
|
|
| 151 |
|
|
to produce
|
| 152 |
|
|
|
| 153 |
|
|
Hello, World!
|
| 154 |
|
|
|
| 155 |
|
|
instead of the
|
| 156 |
|
|
|
| 157 |
|
|
Hello, <b>World<b>!
|
| 158 |
|
|
|
| 159 |
|
|
that would have been produced if {{.}} was a regular string.
|
| 160 |
|
|
|
| 161 |
|
|
|
| 162 |
|
|
Security Model
|
| 163 |
|
|
|
| 164 |
|
|
http://js-quasis-libraries-and-repl.googlecode.com/svn/trunk/safetemplate.html#problem_definition defines "safe" as used by this package.
|
| 165 |
|
|
|
| 166 |
|
|
This package assumes that template authors are trusted, that Execute's data
|
| 167 |
|
|
parameter is not, and seeks to preserve the properties below in the face
|
| 168 |
|
|
of untrusted data:
|
| 169 |
|
|
|
| 170 |
|
|
Structure Preservation Property
|
| 171 |
|
|
"... when a template author writes an HTML tag in a safe templating language,
|
| 172 |
|
|
the browser will interpret the corresponding portion of the output as a tag
|
| 173 |
|
|
regardless of the values of untrusted data, and similarly for other structures
|
| 174 |
|
|
such as attribute boundaries and JS and CSS string boundaries."
|
| 175 |
|
|
|
| 176 |
|
|
Code Effect Property
|
| 177 |
|
|
"... only code specified by the template author should run as a result of
|
| 178 |
|
|
injecting the template output into a page and all code specified by the
|
| 179 |
|
|
template author should run as a result of the same."
|
| 180 |
|
|
|
| 181 |
|
|
Least Surprise Property
|
| 182 |
|
|
"A developer (or code reviewer) familiar with HTML, CSS, and JavaScript, who
|
| 183 |
|
|
knows that contextual autoescaping happens should be able to look at a {{.}}
|
| 184 |
|
|
and correctly infer what sanitization happens."
|
| 185 |
|
|
*/
|
| 186 |
|
|
package template
|