legacyconversions.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // Copyright 2013 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Transitional utilities to unsafely trust random strings as
  16. * goog.html types. Intended for temporary use when upgrading a library that
  17. * used to accept plain strings to use safe types, but where it's not
  18. * practical to transitively update callers.
  19. *
  20. * IMPORTANT: No new code should use the conversion functions in this file,
  21. * they are intended for refactoring old code to use goog.html types. New code
  22. * should construct goog.html types via their APIs, template systems or
  23. * sanitizers. If that’s not possible it should use
  24. * goog.html.uncheckedconversions and undergo security review.
  25. *
  26. * The semantics of the conversions in goog.html.legacyconversions are very
  27. * different from the ones provided by goog.html.uncheckedconversions. The
  28. * latter are for use in code where it has been established through manual
  29. * security review that the value produced by a piece of code will always
  30. * satisfy the SafeHtml contract (e.g., the output of a secure HTML sanitizer).
  31. * In uses of goog.html.legacyconversions, this guarantee is not given -- the
  32. * value in question originates in unreviewed legacy code and there is no
  33. * guarantee that it satisfies the SafeHtml contract.
  34. *
  35. * There are only three valid uses of legacyconversions:
  36. *
  37. * 1. Introducing a goog.html version of a function which currently consumes
  38. * string and passes that string to a DOM API which can execute script - and
  39. * hence cause XSS - like innerHTML. For example, Dialog might expose a
  40. * setContent method which takes a string and sets the innerHTML property of
  41. * an element with it. In this case a setSafeHtmlContent function could be
  42. * added, consuming goog.html.SafeHtml instead of string, and using
  43. * goog.dom.safe.setInnerHtml instead of directly setting innerHTML.
  44. * setContent could then internally use legacyconversions to create a SafeHtml
  45. * from string and pass the SafeHtml to setSafeHtmlContent. In this scenario
  46. * remember to document the use of legacyconversions in the modified setContent
  47. * and consider deprecating it as well.
  48. *
  49. * 2. Automated refactoring of application code which handles HTML as string
  50. * but needs to call a function which only takes goog.html types. For example,
  51. * in the Dialog scenario from (1) an alternative option would be to refactor
  52. * setContent to accept goog.html.SafeHtml instead of string and then refactor
  53. * all current callers to use legacyconversions to pass SafeHtml. This is
  54. * generally preferable to (1) because it keeps the library clean of
  55. * legacyconversions, and makes code sites in application code that are
  56. * potentially vulnerable to XSS more apparent.
  57. *
  58. * 3. Old code which needs to call APIs which consume goog.html types and for
  59. * which it is prohibitively expensive to refactor to use goog.html types.
  60. * Generally, this is code where safety from XSS is either hopeless or
  61. * unimportant.
  62. *
  63. * @visibility {//closure/goog/html:approved_for_legacy_conversion}
  64. * @visibility {//closure/goog/bin/sizetests:__pkg__}
  65. */
  66. goog.provide('goog.html.legacyconversions');
  67. goog.require('goog.html.SafeHtml');
  68. goog.require('goog.html.SafeStyle');
  69. goog.require('goog.html.SafeStyleSheet');
  70. goog.require('goog.html.SafeUrl');
  71. goog.require('goog.html.TrustedResourceUrl');
  72. /**
  73. * Performs an "unchecked conversion" from string to SafeHtml for legacy API
  74. * purposes.
  75. *
  76. * Please read fileoverview documentation before using.
  77. *
  78. * @param {string} html A string to be converted to SafeHtml.
  79. * @return {!goog.html.SafeHtml} The value of html, wrapped in a SafeHtml
  80. * object.
  81. */
  82. goog.html.legacyconversions.safeHtmlFromString = function(html) {
  83. goog.html.legacyconversions.reportCallback_();
  84. return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
  85. html, null /* dir */);
  86. };
  87. /**
  88. * Performs an "unchecked conversion" from string to SafeStyle for legacy API
  89. * purposes.
  90. *
  91. * Please read fileoverview documentation before using.
  92. *
  93. * @param {string} style A string to be converted to SafeStyle.
  94. * @return {!goog.html.SafeStyle} The value of style, wrapped in a SafeStyle
  95. * object.
  96. */
  97. goog.html.legacyconversions.safeStyleFromString = function(style) {
  98. goog.html.legacyconversions.reportCallback_();
  99. return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(
  100. style);
  101. };
  102. /**
  103. * Performs an "unchecked conversion" from string to SafeStyleSheet for legacy
  104. * API purposes.
  105. *
  106. * Please read fileoverview documentation before using.
  107. *
  108. * @param {string} styleSheet A string to be converted to SafeStyleSheet.
  109. * @return {!goog.html.SafeStyleSheet} The value of style sheet, wrapped in
  110. * a SafeStyleSheet object.
  111. */
  112. goog.html.legacyconversions.safeStyleSheetFromString = function(styleSheet) {
  113. goog.html.legacyconversions.reportCallback_();
  114. return goog.html.SafeStyleSheet
  115. .createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheet);
  116. };
  117. /**
  118. * Performs an "unchecked conversion" from string to SafeUrl for legacy API
  119. * purposes.
  120. *
  121. * Please read fileoverview documentation before using.
  122. *
  123. * @param {string} url A string to be converted to SafeUrl.
  124. * @return {!goog.html.SafeUrl} The value of url, wrapped in a SafeUrl
  125. * object.
  126. */
  127. goog.html.legacyconversions.safeUrlFromString = function(url) {
  128. goog.html.legacyconversions.reportCallback_();
  129. return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
  130. };
  131. /**
  132. * Performs an "unchecked conversion" from string to TrustedResourceUrl for
  133. * legacy API purposes.
  134. *
  135. * Please read fileoverview documentation before using.
  136. *
  137. * @param {string} url A string to be converted to TrustedResourceUrl.
  138. * @return {!goog.html.TrustedResourceUrl} The value of url, wrapped in a
  139. * TrustedResourceUrl object.
  140. */
  141. goog.html.legacyconversions.trustedResourceUrlFromString = function(url) {
  142. goog.html.legacyconversions.reportCallback_();
  143. return goog.html.TrustedResourceUrl
  144. .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(url);
  145. };
  146. /**
  147. * @private {function(): undefined}
  148. */
  149. goog.html.legacyconversions.reportCallback_ = goog.nullFunction;
  150. /**
  151. * Sets a function that will be called every time a legacy conversion is
  152. * performed. The function is called with no parameters but it can use
  153. * goog.debug.getStacktrace to get a stacktrace.
  154. *
  155. * @param {function(): undefined} callback Error callback as defined above.
  156. */
  157. goog.html.legacyconversions.setReportCallback = function(callback) {
  158. goog.html.legacyconversions.reportCallback_ = callback;
  159. };