Home | History | Annotate | Download | only in template
      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 package 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 package 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 The security model used by this package assumes that template authors are
     32 trusted, while Execute's data parameter is not. More details are
     33 provided below.
     34 
     35 Example
     36 
     37   import "text/template"
     38   ...
     39   t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
     40   err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")
     41 
     42 produces
     43 
     44   Hello, <script>alert('you have been pwned')</script>!
     45 
     46 but the contextual autoescaping in html/template
     47 
     48   import "html/template"
     49   ...
     50   t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
     51   err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")
     52 
     53 produces safe, escaped HTML output
     54 
     55   Hello, &lt;script&gt;alert(&#39;you have been pwned&#39;)&lt;/script&gt;!
     56 
     57 
     58 Contexts
     59 
     60 This package understands HTML, CSS, JavaScript, and URIs. It adds sanitizing
     61 functions to each simple action pipeline, so given the excerpt
     62 
     63   <a href="/search?q={{.}}">{{.}}</a>
     64 
     65 At parse time each {{.}} is overwritten to add escaping functions as necessary.
     66 In this case it becomes
     67 
     68   <a href="/search?q={{. | urlescaper | attrescaper}}">{{. | htmlescaper}}</a>
     69 
     70 where urlescaper, attrescaper, and htmlescaper are aliases for internal escaping
     71 functions.
     72 
     73 Errors
     74 
     75 See the documentation of ErrorCode for details.
     76 
     77 
     78 A fuller picture
     79 
     80 The rest of this package comment may be skipped on first reading; it includes
     81 details necessary to understand escaping contexts and error messages. Most users
     82 will not need to understand these details.
     83 
     84 
     85 Contexts
     86 
     87 Assuming {{.}} is `O'Reilly: How are <i>you</i>?`, the table below shows
     88 how {{.}} appears when used in the context to the left.
     89 
     90   Context                          {{.}} After
     91   {{.}}                            O'Reilly: How are &lt;i&gt;you&lt;/i&gt;?
     92   <a title='{{.}}'>                O&#39;Reilly: How are you?
     93   <a href="/{{.}}">                O&#39;Reilly: How are %3ci%3eyou%3c/i%3e?
     94   <a href="?q={{.}}">              O&#39;Reilly%3a%20How%20are%3ci%3e...%3f
     95   <a onx='f("{{.}}")'>             O\x27Reilly: How are \x3ci\x3eyou...?
     96   <a onx='f({{.}})'>               "O\x27Reilly: How are \x3ci\x3eyou...?"
     97   <a onx='pattern = /{{.}}/;'>     O\x27Reilly: How are \x3ci\x3eyou...\x3f
     98 
     99 If used in an unsafe context, then the value might be filtered out:
    100 
    101   Context                          {{.}} After
    102   <a href="{{.}}">                 #ZgotmplZ
    103 
    104 since "O'Reilly:" is not an allowed protocol like "http:".
    105 
    106 
    107 If {{.}} is the innocuous word, `left`, then it can appear more widely,
    108 
    109   Context                              {{.}} After
    110   {{.}}                                left
    111   <a title='{{.}}'>                    left
    112   <a href='{{.}}'>                     left
    113   <a href='/{{.}}'>                    left
    114   <a href='?dir={{.}}'>                left
    115   <a style="border-{{.}}: 4px">        left
    116   <a style="align: {{.}}">             left
    117   <a style="background: '{{.}}'>       left
    118   <a style="background: url('{{.}}')>  left
    119   <style>p.{{.}} {color:red}</style>   left
    120 
    121 Non-string values can be used in JavaScript contexts.
    122 If {{.}} is
    123 
    124   struct{A,B string}{ "foo", "bar" }
    125 
    126 in the escaped template
    127 
    128   <script>var pair = {{.}};</script>
    129 
    130 then the template output is
    131 
    132   <script>var pair = {"A": "foo", "B": "bar"};</script>
    133 
    134 See package json to understand how non-string content is marshaled for
    135 embedding in JavaScript contexts.
    136 
    137 
    138 Typed Strings
    139 
    140 By default, this package assumes that all pipelines produce a plain text string.
    141 It adds escaping pipeline stages necessary to correctly and safely embed that
    142 plain text string in the appropriate context.
    143 
    144 When a data value is not plain text, you can make sure it is not over-escaped
    145 by marking it with its type.
    146 
    147 Types HTML, JS, URL, and others from content.go can carry safe content that is
    148 exempted from escaping.
    149 
    150 The template
    151 
    152   Hello, {{.}}!
    153 
    154 can be invoked with
    155 
    156   tmpl.Execute(out, template.HTML(`<b>World</b>`))
    157 
    158 to produce
    159 
    160   Hello, <b>World</b>!
    161 
    162 instead of the
    163 
    164   Hello, &lt;b&gt;World&lt;b&gt;!
    165 
    166 that would have been produced if {{.}} was a regular string.
    167 
    168 
    169 Security Model
    170 
    171 https://rawgit.com/mikesamuel/sanitized-jquery-templates/trunk/safetemplate.html#problem_definition defines "safe" as used by this package.
    172 
    173 This package assumes that template authors are trusted, that Execute's data
    174 parameter is not, and seeks to preserve the properties below in the face
    175 of untrusted data:
    176 
    177 Structure Preservation Property:
    178 "... when a template author writes an HTML tag in a safe templating language,
    179 the browser will interpret the corresponding portion of the output as a tag
    180 regardless of the values of untrusted data, and similarly for other structures
    181 such as attribute boundaries and JS and CSS string boundaries."
    182 
    183 Code Effect Property:
    184 "... only code specified by the template author should run as a result of
    185 injecting the template output into a page and all code specified by the
    186 template author should run as a result of the same."
    187 
    188 Least Surprise Property:
    189 "A developer (or code reviewer) familiar with HTML, CSS, and JavaScript, who
    190 knows that contextual autoescaping happens should be able to look at a {{.}}
    191 and correctly infer what sanitization happens."
    192 */
    193 package template
    194