attr.go 6.2 KB

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