...

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

View as plain text