github.com/filosottile/go@v0.0.0-20170906193555-dbed9972d994/src/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  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