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.
11 // attrTypeMap[n] describes the value of the given attribute.
12 // If an attribute affects (or can mask) the encoding or interpretation of
13 // other content, or affects the contents, idempotency, or credentials of a
14 // network message, then the value in this map is contentTypeUnsafe.
15 // This map is derived from HTML5, specifically
16 // http://www.w3.org/TR/html5/Overview.html#attributes-1
17 // as well as "%URI"-typed attributes from
18 // http://www.w3.org/TR/html4/index/attributes.html
19 var attrTypeMap
= map[string]contentType
{
20 "accept": contentTypePlain
,
21 "accept-charset": contentTypeUnsafe
,
22 "action": contentTypeURL
,
23 "alt": contentTypePlain
,
24 "archive": contentTypeURL
,
25 "async": contentTypeUnsafe
,
26 "autocomplete": contentTypePlain
,
27 "autofocus": contentTypePlain
,
28 "autoplay": contentTypePlain
,
29 "background": contentTypeURL
,
30 "border": contentTypePlain
,
31 "checked": contentTypePlain
,
32 "cite": contentTypeURL
,
33 "challenge": contentTypeUnsafe
,
34 "charset": contentTypeUnsafe
,
35 "class": contentTypePlain
,
36 "classid": contentTypeURL
,
37 "codebase": contentTypeURL
,
38 "cols": contentTypePlain
,
39 "colspan": contentTypePlain
,
40 "content": contentTypeUnsafe
,
41 "contenteditable": contentTypePlain
,
42 "contextmenu": contentTypePlain
,
43 "controls": contentTypePlain
,
44 "coords": contentTypePlain
,
45 "crossorigin": contentTypeUnsafe
,
46 "data": contentTypeURL
,
47 "datetime": contentTypePlain
,
48 "default": contentTypePlain
,
49 "defer": contentTypeUnsafe
,
50 "dir": contentTypePlain
,
51 "dirname": contentTypePlain
,
52 "disabled": contentTypePlain
,
53 "draggable": contentTypePlain
,
54 "dropzone": contentTypePlain
,
55 "enctype": contentTypeUnsafe
,
56 "for": contentTypePlain
,
57 "form": contentTypeUnsafe
,
58 "formaction": contentTypeURL
,
59 "formenctype": contentTypeUnsafe
,
60 "formmethod": contentTypeUnsafe
,
61 "formnovalidate": contentTypeUnsafe
,
62 "formtarget": contentTypePlain
,
63 "headers": contentTypePlain
,
64 "height": contentTypePlain
,
65 "hidden": contentTypePlain
,
66 "high": contentTypePlain
,
67 "href": contentTypeURL
,
68 "hreflang": contentTypePlain
,
69 "http-equiv": contentTypeUnsafe
,
70 "icon": contentTypeURL
,
71 "id": contentTypePlain
,
72 "ismap": contentTypePlain
,
73 "keytype": contentTypeUnsafe
,
74 "kind": contentTypePlain
,
75 "label": contentTypePlain
,
76 "lang": contentTypePlain
,
77 "language": contentTypeUnsafe
,
78 "list": contentTypePlain
,
79 "longdesc": contentTypeURL
,
80 "loop": contentTypePlain
,
81 "low": contentTypePlain
,
82 "manifest": contentTypeURL
,
83 "max": contentTypePlain
,
84 "maxlength": contentTypePlain
,
85 "media": contentTypePlain
,
86 "mediagroup": contentTypePlain
,
87 "method": contentTypeUnsafe
,
88 "min": contentTypePlain
,
89 "multiple": contentTypePlain
,
90 "name": contentTypePlain
,
91 "novalidate": contentTypeUnsafe
,
92 // Skip handler names from
93 // http://www.w3.org/TR/html5/webappapis.html#event-handlers-on-elements,-document-objects,-and-window-objects
94 // since we have special handling in attrType.
95 "open": contentTypePlain
,
96 "optimum": contentTypePlain
,
97 "pattern": contentTypeUnsafe
,
98 "placeholder": contentTypePlain
,
99 "poster": contentTypeURL
,
100 "profile": contentTypeURL
,
101 "preload": contentTypePlain
,
102 "pubdate": contentTypePlain
,
103 "radiogroup": contentTypePlain
,
104 "readonly": contentTypePlain
,
105 "rel": contentTypeUnsafe
,
106 "required": contentTypePlain
,
107 "reversed": contentTypePlain
,
108 "rows": contentTypePlain
,
109 "rowspan": contentTypePlain
,
110 "sandbox": contentTypeUnsafe
,
111 "spellcheck": contentTypePlain
,
112 "scope": contentTypePlain
,
113 "scoped": contentTypePlain
,
114 "seamless": contentTypePlain
,
115 "selected": contentTypePlain
,
116 "shape": contentTypePlain
,
117 "size": contentTypePlain
,
118 "sizes": contentTypePlain
,
119 "span": contentTypePlain
,
120 "src": contentTypeURL
,
121 "srcdoc": contentTypeHTML
,
122 "srclang": contentTypePlain
,
123 "srcset": contentTypeSrcset
,
124 "start": contentTypePlain
,
125 "step": contentTypePlain
,
126 "style": contentTypeCSS
,
127 "tabindex": contentTypePlain
,
128 "target": contentTypePlain
,
129 "title": contentTypePlain
,
130 "type": contentTypeUnsafe
,
131 "usemap": contentTypeURL
,
132 "value": contentTypeUnsafe
,
133 "width": contentTypePlain
,
134 "wrap": contentTypePlain
,
135 "xmlns": contentTypeURL
,
138 // attrType returns a conservative (upper-bound on authority) guess at the
139 // type of the lowercase named attribute.
140 func attrType(name
string) contentType
{
141 if strings
.HasPrefix(name
, "data-") {
142 // Strip data- so that custom attribute heuristics below are
144 // Treat data-action as URL below.
146 } else if colon
:= strings
.IndexRune(name
, ':'); colon
!= -1 {
147 if name
[:colon
] == "xmlns" {
148 return contentTypeURL
150 // Treat svg:href and xlink:href as href below.
151 name
= name
[colon
+1:]
153 if t
, ok
:= attrTypeMap
[name
]; ok
{
156 // Treat partial event handler names as script.
157 if strings
.HasPrefix(name
, "on") {
161 // Heuristics to prevent "javascript:..." injection in custom
162 // data attributes and custom attributes like g:tweetUrl.
163 // http://www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes
164 // "Custom data attributes are intended to store custom data
165 // private to the page or application, for which there are no
166 // more appropriate attributes or elements."
167 // Developers seem to store URL content in data URLs that start
168 // or end with "URI" or "URL".
169 if strings
.Contains(name
, "src") ||
170 strings
.Contains(name
, "uri") ||
171 strings
.Contains(name
, "url") {
172 return contentTypeURL
174 return contentTypePlain