dompurify 3.0.2 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG.
8
8
 
9
- It's also very simple to use and get started with. DOMPurify was [started in February 2014](https://github.com/cure53/DOMPurify/commit/a630922616927373485e0e787ab19e73e3691b2b) and, meanwhile, has reached version **v3.0.2**.
9
+ It's also very simple to use and get started with. DOMPurify was [started in February 2014](https://github.com/cure53/DOMPurify/commit/a630922616927373485e0e787ab19e73e3691b2b) and, meanwhile, has reached version **v3.0.3**.
10
10
 
11
11
  DOMPurify is written in JavaScript and works in all modern browsers (Safari (10+), Opera (15+), Edge, Firefox and Chrome - as well as almost anything else using Blink, Gecko or WebKit). It doesn't break on MSIE or other legacy browsers. It simply does nothing.
12
12
 
@@ -291,6 +291,15 @@ var clean = DOMPurify.sanitize(dirty, {RETURN_DOM_FRAGMENT: true});
291
291
  // use the RETURN_TRUSTED_TYPE flag to turn on Trusted Types support if available
292
292
  var clean = DOMPurify.sanitize(dirty, {RETURN_TRUSTED_TYPE: true}); // will return a TrustedHTML object instead of a string if possible
293
293
 
294
+ // use a provided Trusted Types policy
295
+ var clean = DOMPurify.sanitize(dirty, {
296
+ // supplied policy must define createHTML and createScriptURL
297
+ TRUSTED_TYPES_POLICY: trustedTypes.createPolicy({
298
+ createHTML(s) { return s},
299
+ createScriptURL(s) { return s},
300
+ }
301
+ });
302
+
294
303
  /**
295
304
  * Influence how we sanitize
296
305
  */
@@ -301,8 +310,8 @@ var clean = DOMPurify.sanitize(dirty, {WHOLE_DOCUMENT: true});
301
310
  var clean = DOMPurify.sanitize(dirty, {SANITIZE_DOM: false});
302
311
 
303
312
  // enforce strict DOM Clobbering protection via namespace isolation (default is false)
304
- // when enabled, isolates the namespace of named properties (i.e., `id` and `name` attributes)
305
- // from JS variables by prefixing them with the string `user-content-`
313
+ // when enabled, isolates the namespace of named properties (i.e., `id` and `name` attributes)
314
+ // from JS variables by prefixing them with the string `user-content-`
306
315
  var clean = DOMPurify.sanitize(dirty, {SANITIZE_NAMED_PROPS: true});
307
316
 
308
317
  // keep an element's content when the element is removed (default is true)
@@ -1,4 +1,4 @@
1
- /*! @license DOMPurify 3.0.2 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.2/LICENSE */
1
+ /*! @license DOMPurify 3.0.3 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.3/LICENSE */
2
2
 
3
3
  'use strict';
4
4
 
@@ -76,7 +76,9 @@ function unconstruct(func) {
76
76
  /* Add properties to a lookup table */
77
77
 
78
78
  function addToSet(set, array, transformCaseFunc) {
79
- transformCaseFunc = transformCaseFunc ? transformCaseFunc : stringToLowerCase;
79
+ var _transformCaseFunc;
80
+
81
+ transformCaseFunc = (_transformCaseFunc = transformCaseFunc) !== null && _transformCaseFunc !== void 0 ? _transformCaseFunc : stringToLowerCase;
80
82
 
81
83
  if (setPrototypeOf) {
82
84
  // Make 'in' and truthy checks like Boolean(set.constructor)
@@ -150,12 +152,12 @@ function lookupGetter(object, prop) {
150
152
  const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']); // SVG
151
153
 
152
154
  const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
153
- const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); // List of SVG elements that are disallowed by default.
155
+ const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); // List of SVG elements that are disallowed by default.
154
156
  // We still need to know them so that we can do namespace
155
157
  // checks properly in case one wants to add them to
156
158
  // allow-list.
157
159
 
158
- const svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'fedropshadow', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);
160
+ const svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);
159
161
  const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']); // Similarly to SVG, we want to know all MathML elements,
160
162
  // even those that we disallow by default.
161
163
 
@@ -200,13 +202,13 @@ const getGlobal = () => typeof window === 'undefined' ? null : window;
200
202
  * Creates a no-op policy for internal use only.
201
203
  * Don't export this function outside this module!
202
204
  * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory.
203
- * @param {Document} document The document object (to determine policy name suffix)
205
+ * @param {HTMLScriptElement} purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).
204
206
  * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types
205
- * are not supported).
207
+ * are not supported or creating the policy failed).
206
208
  */
207
209
 
208
210
 
209
- const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) {
211
+ const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {
210
212
  if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
211
213
  return null;
212
214
  } // Allow the callers to control the unique policy name
@@ -217,8 +219,8 @@ const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedType
217
219
  let suffix = null;
218
220
  const ATTR_NAME = 'data-tt-policy-suffix';
219
221
 
220
- if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) {
221
- suffix = document.currentScript.getAttribute(ATTR_NAME);
222
+ if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
223
+ suffix = purifyHostElement.getAttribute(ATTR_NAME);
222
224
  }
223
225
 
224
226
  const policyName = 'dompurify' + (suffix ? '#' + suffix : '');
@@ -253,7 +255,7 @@ function createDOMPurify() {
253
255
  */
254
256
 
255
257
 
256
- DOMPurify.version = '3.0.2';
258
+ DOMPurify.version = '3.0.3';
257
259
  /**
258
260
  * Array of elements that DOMPurify removed during sanitation.
259
261
  * Empty if nothing was removed.
@@ -269,6 +271,7 @@ function createDOMPurify() {
269
271
  }
270
272
 
271
273
  const originalDocument = window.document;
274
+ const currentScript = originalDocument.currentScript;
272
275
  let {
273
276
  document
274
277
  } = window;
@@ -302,9 +305,8 @@ function createDOMPurify() {
302
305
  }
303
306
  }
304
307
 
305
- const trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);
306
-
307
- const emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';
308
+ let trustedTypesPolicy;
309
+ let emptyHTML = '';
308
310
  const {
309
311
  implementation,
310
312
  createNodeIterator,
@@ -319,7 +321,7 @@ function createDOMPurify() {
319
321
  * Expose whether this browser supports running the full DOMPurify.
320
322
  */
321
323
 
322
- DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined';
324
+ DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;
323
325
  const {
324
326
  MUSTACHE_EXPR,
325
327
  ERB_EXPR,
@@ -666,6 +668,31 @@ function createDOMPurify() {
666
668
  if (ALLOWED_TAGS.table) {
667
669
  addToSet(ALLOWED_TAGS, ['tbody']);
668
670
  delete FORBID_TAGS.tbody;
671
+ }
672
+
673
+ if (cfg.TRUSTED_TYPES_POLICY) {
674
+ if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {
675
+ throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
676
+ }
677
+
678
+ if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {
679
+ throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
680
+ } // Overwrite existing TrustedTypes policy.
681
+
682
+
683
+ trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY; // Sign local variables required by `sanitize`.
684
+
685
+ emptyHTML = trustedTypesPolicy.createHTML('');
686
+ } else {
687
+ // Uninitialized policy, attempt to initialize the internal dompurify policy.
688
+ if (trustedTypesPolicy === undefined) {
689
+ trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
690
+ } // If creating the internal policy succeeded sign internal variables.
691
+
692
+
693
+ if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {
694
+ emptyHTML = trustedTypesPolicy.createHTML('');
695
+ }
669
696
  } // Prevent further manipulation of configuration.
670
697
  // Not available in IE8, Safari 5, etc.
671
698
 
@@ -1102,9 +1129,9 @@ function createDOMPurify() {
1102
1129
  }
1103
1130
  /* Check value is safe. First, is attr inert? If so, is safe */
1104
1131
 
1105
- } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (!value) ; else {
1132
+ } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) {
1106
1133
  return false;
1107
- }
1134
+ } else ;
1108
1135
 
1109
1136
  return true;
1110
1137
  };
@@ -1234,12 +1261,16 @@ function createDOMPurify() {
1234
1261
  if (namespaceURI) ; else {
1235
1262
  switch (trustedTypes.getAttributeType(lcTag, lcName)) {
1236
1263
  case 'TrustedHTML':
1237
- value = trustedTypesPolicy.createHTML(value);
1238
- break;
1264
+ {
1265
+ value = trustedTypesPolicy.createHTML(value);
1266
+ break;
1267
+ }
1239
1268
 
1240
1269
  case 'TrustedScriptURL':
1241
- value = trustedTypesPolicy.createScriptURL(value);
1242
- break;
1270
+ {
1271
+ value = trustedTypesPolicy.createScriptURL(value);
1272
+ break;
1273
+ }
1243
1274
  }
1244
1275
  }
1245
1276
  }
@@ -1332,15 +1363,14 @@ function createDOMPurify() {
1332
1363
 
1333
1364
 
1334
1365
  if (typeof dirty !== 'string' && !_isNode(dirty)) {
1335
- // eslint-disable-next-line no-negated-condition
1336
- if (typeof dirty.toString !== 'function') {
1337
- throw typeErrorCreate('toString is not a function');
1338
- } else {
1366
+ if (typeof dirty.toString === 'function') {
1339
1367
  dirty = dirty.toString();
1340
1368
 
1341
1369
  if (typeof dirty !== 'string') {
1342
1370
  throw typeErrorCreate('dirty is not a string, aborting');
1343
1371
  }
1372
+ } else {
1373
+ throw typeErrorCreate('toString is not a function');
1344
1374
  }
1345
1375
  }
1346
1376
  /* Return dirty HTML if DOMPurify cannot run */