dompurify 2.4.4 → 3.0.0

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/LICENSE CHANGED
@@ -1,5 +1,5 @@
1
1
  DOMPurify
2
- Copyright 2015 Mario Heiderich
2
+ Copyright 2023 Dr.-Ing. Mario Heiderich, Cure53
3
3
 
4
4
  DOMPurify is free software; you can redistribute it and/or modify it under the
5
5
  terms of either:
package/README.md CHANGED
@@ -6,13 +6,13 @@
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 2.4.4.
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 3.0.0.
10
10
 
11
- DOMPurify is written in JavaScript and works in all modern browsers (Safari (10+), Opera (15+), Internet Explorer (10+), Edge, Firefox and Chrome - as well as almost anything else using Blink or WebKit). It doesn't break on MSIE6 or other legacy browsers. It either uses [a fall-back](#what-about-older-browsers-like-msie8) or simply does nothing.
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
 
13
- **Note that DOMPurify v2.4.4 is the final version supporting MSIE. For important security updates compatible with MSIE, please use the 2.x branch.**
13
+ **Note that [DOMPurify v2.4.4](https://github.com/cure53/DOMPurify/releases/tag/2.4.4) is the final version supporting MSIE. For important security updates compatible with MSIE, please use the [2.x branch](https://github.com/cure53/DOMPurify/tree/2.x).**
14
14
 
15
- Our automated tests cover [19 different browsers](https://github.com/cure53/DOMPurify/blob/main/test/karma.custom-launchers.config.js#L5) right now, more to come. We also cover Node.js v14.x, v16.x, v17.x and v18.x, running DOMPurify on [jsdom](https://github.com/jsdom/jsdom). Older Node versions are known to work as well, but hey... no guarantees.
15
+ Our automated tests cover [19 different browsers](https://github.com/cure53/DOMPurify/blob/main/test/karma.custom-launchers.config.js#L5) right now, more to come. We also cover Node.js v16.x, v17.x, v18.x and v19.x, running DOMPurify on [jsdom](https://github.com/jsdom/jsdom). Older Node versions are known to work as well, but hey... no guarantees.
16
16
 
17
17
  DOMPurify is written by security people who have vast background in web attacks and XSS. Fear not. For more details please also read about our [Security Goals & Threat Model](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model). Please, read it. Like, really.
18
18
 
@@ -145,13 +145,9 @@ DOMPurify.sanitize('<UL><li><A HREF=//google.com>click</UL>'); // becomes <ul><l
145
145
 
146
146
  DOMPurify currently supports HTML5, SVG and MathML. DOMPurify per default allows CSS, HTML custom data attributes. DOMPurify also supports the Shadow DOM - and sanitizes DOM templates recursively. DOMPurify also allows you to sanitize HTML for being used with the jQuery `$()` and `elm.html()` API without any known problems.
147
147
 
148
- ## What about older browsers like MSIE8?
148
+ ## What about legacy browsers like Internet Explorer?
149
149
 
150
- DOMPurify offers a fall-back behavior for older MSIE browsers. It uses the MSIE-only `toStaticHTML` feature to sanitize. Note however that in this fall-back mode, pretty much none of the configuration flags shown below have any effect. You need to handle that yourself.
151
-
152
- If not even `toStaticHTML` is supported, DOMPurify does nothing at all. It simply returns exactly the string that you fed it.
153
-
154
- DOMPurify also exposes a property called `isSupported`, which tells you whether DOMPurify will be able to do its job.
150
+ DOMPurify does nothing at all. It simply returns exactly the string that you fed it. DOMPurify exposes a property called `isSupported`, which tells you whether it will be able to do its job, so you can come up with your own backup plan.
155
151
 
156
152
  ## What about DOMPurify and Trusted Types?
157
153
 
@@ -1,4 +1,4 @@
1
- /*! @license DOMPurify 2.4.4 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.4.4/LICENSE */
1
+ /*! @license DOMPurify 3.0.0 | (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.0/LICENSE */
2
2
 
3
3
  'use strict';
4
4
 
@@ -51,6 +51,10 @@ function _construct(Parent, args, Class) {
51
51
  return _construct.apply(null, arguments);
52
52
  }
53
53
 
54
+ function _slicedToArray(arr, i) {
55
+ return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
56
+ }
57
+
54
58
  function _toConsumableArray(arr) {
55
59
  return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
56
60
  }
@@ -59,10 +63,44 @@ function _arrayWithoutHoles(arr) {
59
63
  if (Array.isArray(arr)) return _arrayLikeToArray(arr);
60
64
  }
61
65
 
66
+ function _arrayWithHoles(arr) {
67
+ if (Array.isArray(arr)) return arr;
68
+ }
69
+
62
70
  function _iterableToArray(iter) {
63
71
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
64
72
  }
65
73
 
74
+ function _iterableToArrayLimit(arr, i) {
75
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
76
+
77
+ if (_i == null) return;
78
+ var _arr = [];
79
+ var _n = true;
80
+ var _d = false;
81
+
82
+ var _s, _e;
83
+
84
+ try {
85
+ for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
86
+ _arr.push(_s.value);
87
+
88
+ if (i && _arr.length === i) break;
89
+ }
90
+ } catch (err) {
91
+ _d = true;
92
+ _e = err;
93
+ } finally {
94
+ try {
95
+ if (!_n && _i["return"] != null) _i["return"]();
96
+ } finally {
97
+ if (_d) throw _e;
98
+ }
99
+ }
100
+
101
+ return _arr;
102
+ }
103
+
66
104
  function _unsupportedIterableToArray(o, minLen) {
67
105
  if (!o) return;
68
106
  if (typeof o === "string") return _arrayLikeToArray(o, minLen);
@@ -84,7 +122,68 @@ function _nonIterableSpread() {
84
122
  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
85
123
  }
86
124
 
87
- var hasOwnProperty = Object.hasOwnProperty,
125
+ function _nonIterableRest() {
126
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
127
+ }
128
+
129
+ function _createForOfIteratorHelper(o, allowArrayLike) {
130
+ var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
131
+
132
+ if (!it) {
133
+ if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
134
+ if (it) o = it;
135
+ var i = 0;
136
+
137
+ var F = function () {};
138
+
139
+ return {
140
+ s: F,
141
+ n: function () {
142
+ if (i >= o.length) return {
143
+ done: true
144
+ };
145
+ return {
146
+ done: false,
147
+ value: o[i++]
148
+ };
149
+ },
150
+ e: function (e) {
151
+ throw e;
152
+ },
153
+ f: F
154
+ };
155
+ }
156
+
157
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
158
+ }
159
+
160
+ var normalCompletion = true,
161
+ didErr = false,
162
+ err;
163
+ return {
164
+ s: function () {
165
+ it = it.call(o);
166
+ },
167
+ n: function () {
168
+ var step = it.next();
169
+ normalCompletion = step.done;
170
+ return step;
171
+ },
172
+ e: function (e) {
173
+ didErr = true;
174
+ err = e;
175
+ },
176
+ f: function () {
177
+ try {
178
+ if (!normalCompletion && it.return != null) it.return();
179
+ } finally {
180
+ if (didErr) throw err;
181
+ }
182
+ }
183
+ };
184
+ }
185
+
186
+ var entries = Object.entries,
88
187
  setPrototypeOf = Object.setPrototypeOf,
89
188
  isFrozen = Object.isFrozen,
90
189
  getPrototypeOf = Object.getPrototypeOf,
@@ -189,20 +288,28 @@ function addToSet(set, array, transformCaseFunc) {
189
288
 
190
289
  function clone(object) {
191
290
  var newObject = create(null);
192
- var property;
193
291
 
194
- for (property in object) {
195
- if (apply(hasOwnProperty, object, [property]) === true) {
196
- newObject[property] = object[property];
292
+ var _iterator = _createForOfIteratorHelper(entries(object)),
293
+ _step;
294
+
295
+ try {
296
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
297
+ var _step$value = _slicedToArray(_step.value, 2),
298
+ property = _step$value[0],
299
+ value = _step$value[1];
300
+
301
+ newObject[property] = value;
197
302
  }
303
+ } catch (err) {
304
+ _iterator.e(err);
305
+ } finally {
306
+ _iterator.f();
198
307
  }
199
308
 
200
309
  return newObject;
201
310
  }
202
- /* IE10 doesn't support __lookupGetter__ so lets'
203
- * simulate it. It also automatically checks
204
- * if the prop is function or getter and behaves
205
- * accordingly. */
311
+ /* This method automatically checks if the prop is function
312
+ * or getter and behaves accordingly. */
206
313
 
207
314
  function lookupGetter(object, prop) {
208
315
  while (object !== null) {
@@ -324,7 +431,7 @@ function createDOMPurify() {
324
431
  */
325
432
 
326
433
 
327
- DOMPurify.version = '2.4.4';
434
+ DOMPurify.version = '3.0.0';
328
435
  /**
329
436
  * Array of elements that DOMPurify removed during sanitation.
330
437
  * Empty if nothing was removed.
@@ -379,18 +486,12 @@ function createDOMPurify() {
379
486
  createDocumentFragment = _document.createDocumentFragment,
380
487
  getElementsByTagName = _document.getElementsByTagName;
381
488
  var importNode = originalDocument.importNode;
382
- var documentMode = {};
383
-
384
- try {
385
- documentMode = clone(document).documentMode ? document.documentMode : {};
386
- } catch (_) {}
387
-
388
489
  var hooks = {};
389
490
  /**
390
491
  * Expose whether this browser supports running the full DOMPurify.
391
492
  */
392
493
 
393
- DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;
494
+ DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined';
394
495
  var MUSTACHE_EXPR$1 = MUSTACHE_EXPR,
395
496
  ERB_EXPR$1 = ERB_EXPR,
396
497
  TMPLIT_EXPR$1 = TMPLIT_EXPR,
@@ -869,11 +970,7 @@ function createDOMPurify() {
869
970
  // eslint-disable-next-line unicorn/prefer-dom-node-remove
870
971
  node.parentNode.removeChild(node);
871
972
  } catch (_) {
872
- try {
873
- node.outerHTML = emptyHTML;
874
- } catch (_) {
875
- node.remove();
876
- }
973
+ node.remove();
877
974
  }
878
975
  };
879
976
  /**
@@ -1052,14 +1149,6 @@ function createDOMPurify() {
1052
1149
 
1053
1150
  return true;
1054
1151
  }
1055
- /* Check if tagname contains Unicode */
1056
-
1057
-
1058
- if (regExpTest(/[\u0080-\uFFFF]/, currentNode.nodeName)) {
1059
- _forceRemove(currentNode);
1060
-
1061
- return true;
1062
- }
1063
1152
  /* Now let's check the element's type and name */
1064
1153
 
1065
1154
 
@@ -1078,14 +1167,6 @@ function createDOMPurify() {
1078
1167
 
1079
1168
  return true;
1080
1169
  }
1081
- /* Mitigate a problem with templates inside select */
1082
-
1083
-
1084
- if (tagName === 'select' && regExpTest(/<template/i, currentNode.innerHTML)) {
1085
- _forceRemove(currentNode);
1086
-
1087
- return true;
1088
- }
1089
1170
  /* Remove element if anything forbids its presence */
1090
1171
 
1091
1172
 
@@ -1123,6 +1204,8 @@ function createDOMPurify() {
1123
1204
 
1124
1205
  return true;
1125
1206
  }
1207
+ /* Make sure that older browsers don't get noscript mXSS */
1208
+
1126
1209
 
1127
1210
  if ((tagName === 'noscript' || tagName === 'noembed') && regExpTest(/<\/no(script|embed)/i, currentNode.innerHTML)) {
1128
1211
  _forceRemove(currentNode);
@@ -1399,7 +1482,6 @@ function createDOMPurify() {
1399
1482
  var body;
1400
1483
  var importedNode;
1401
1484
  var currentNode;
1402
- var oldNode;
1403
1485
  var returnNode;
1404
1486
  /* Make sure we have a string to sanitize.
1405
1487
  DO NOT return early, as this will return the wrong type if
@@ -1425,20 +1507,10 @@ function createDOMPurify() {
1425
1507
  }
1426
1508
  }
1427
1509
  }
1428
- /* Check we can run. Otherwise fall back or ignore */
1510
+ /* Return dirty HTML if DOMPurify cannot run */
1429
1511
 
1430
1512
 
1431
1513
  if (!DOMPurify.isSupported) {
1432
- if (_typeof(window.toStaticHTML) === 'object' || typeof window.toStaticHTML === 'function') {
1433
- if (typeof dirty === 'string') {
1434
- return window.toStaticHTML(dirty);
1435
- }
1436
-
1437
- if (_isNode(dirty)) {
1438
- return window.toStaticHTML(dirty.outerHTML);
1439
- }
1440
- }
1441
-
1442
1514
  return dirty;
1443
1515
  }
1444
1516
  /* Assign config vars */
@@ -1511,13 +1583,7 @@ function createDOMPurify() {
1511
1583
 
1512
1584
 
1513
1585
  while (currentNode = nodeIterator.nextNode()) {
1514
- /* Fix IE's strange behavior with manipulated textNodes #89 */
1515
- if (currentNode.nodeType === 3 && currentNode === oldNode) {
1516
- continue;
1517
- }
1518
1586
  /* Sanitize tags and elements */
1519
-
1520
-
1521
1587
  if (_sanitizeElements(currentNode)) {
1522
1588
  continue;
1523
1589
  }
@@ -1531,13 +1597,10 @@ function createDOMPurify() {
1531
1597
 
1532
1598
 
1533
1599
  _sanitizeAttributes(currentNode);
1534
-
1535
- oldNode = currentNode;
1536
1600
  }
1537
-
1538
- oldNode = null;
1539
1601
  /* If we sanitized `dirty` in-place, return it. */
1540
1602
 
1603
+
1541
1604
  if (IN_PLACE) {
1542
1605
  return dirty;
1543
1606
  }