dompurify 3.1.1 → 3.1.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 +3 -3
- package/dist/purify.cjs.js +57 -20
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.mjs +57 -20
- package/dist/purify.es.mjs.map +1 -1
- package/dist/purify.js +57 -20
- package/dist/purify.js.map +1 -1
- package/dist/purify.min.js +2 -2
- package/dist/purify.min.js.map +1 -1
- package/package.json +1 -1
package/dist/purify.es.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @license DOMPurify 3.1.
|
|
1
|
+
/*! @license DOMPurify 3.1.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.1.3/LICENSE */
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
4
|
entries,
|
|
@@ -48,6 +48,7 @@ const stringTrim = unapply(String.prototype.trim);
|
|
|
48
48
|
const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
|
|
49
49
|
const regExpTest = unapply(RegExp.prototype.test);
|
|
50
50
|
const typeErrorCreate = unconstruct(TypeError);
|
|
51
|
+
const numberIsNaN = unapply(Number.isNaN);
|
|
51
52
|
|
|
52
53
|
/**
|
|
53
54
|
* Creates a new function that calls the given function with a specified thisArg and arguments.
|
|
@@ -231,6 +232,24 @@ var EXPRESSIONS = /*#__PURE__*/Object.freeze({
|
|
|
231
232
|
CUSTOM_ELEMENT: CUSTOM_ELEMENT
|
|
232
233
|
});
|
|
233
234
|
|
|
235
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
|
|
236
|
+
const NODE_TYPE = {
|
|
237
|
+
element: 1,
|
|
238
|
+
attribute: 2,
|
|
239
|
+
text: 3,
|
|
240
|
+
cdataSection: 4,
|
|
241
|
+
entityReference: 5,
|
|
242
|
+
// Deprecated
|
|
243
|
+
entityNode: 6,
|
|
244
|
+
// Deprecated
|
|
245
|
+
progressingInstruction: 7,
|
|
246
|
+
comment: 8,
|
|
247
|
+
document: 9,
|
|
248
|
+
documentType: 10,
|
|
249
|
+
documentFragment: 11,
|
|
250
|
+
notation: 12 // Deprecated
|
|
251
|
+
};
|
|
252
|
+
|
|
234
253
|
const getGlobal = function getGlobal() {
|
|
235
254
|
return typeof window === 'undefined' ? null : window;
|
|
236
255
|
};
|
|
@@ -282,14 +301,14 @@ function createDOMPurify() {
|
|
|
282
301
|
* Version label, exposed for easier checks
|
|
283
302
|
* if DOMPurify is up to date or not
|
|
284
303
|
*/
|
|
285
|
-
DOMPurify.version = '3.1.
|
|
304
|
+
DOMPurify.version = '3.1.3';
|
|
286
305
|
|
|
287
306
|
/**
|
|
288
307
|
* Array of elements that DOMPurify removed during sanitation.
|
|
289
308
|
* Empty if nothing was removed.
|
|
290
309
|
*/
|
|
291
310
|
DOMPurify.removed = [];
|
|
292
|
-
if (!window || !window.document || window.document.nodeType !==
|
|
311
|
+
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document) {
|
|
293
312
|
// Not running in a browser, provide a factory function
|
|
294
313
|
// so that you can pass your own Window
|
|
295
314
|
DOMPurify.isSupported = false;
|
|
@@ -704,7 +723,7 @@ function createDOMPurify() {
|
|
|
704
723
|
CONFIG = cfg;
|
|
705
724
|
};
|
|
706
725
|
const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
|
|
707
|
-
const HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', '
|
|
726
|
+
const HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'annotation-xml']);
|
|
708
727
|
|
|
709
728
|
// Certain elements are allowed in both SVG and HTML
|
|
710
729
|
// namespace. We need to specify them explicitly
|
|
@@ -1000,13 +1019,13 @@ function createDOMPurify() {
|
|
|
1000
1019
|
}
|
|
1001
1020
|
|
|
1002
1021
|
/* Remove any ocurrence of processing instructions */
|
|
1003
|
-
if (currentNode.nodeType ===
|
|
1022
|
+
if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
|
|
1004
1023
|
_forceRemove(currentNode);
|
|
1005
1024
|
return true;
|
|
1006
1025
|
}
|
|
1007
1026
|
|
|
1008
1027
|
/* Remove any kind of possibly harmful comments */
|
|
1009
|
-
if (SAFE_FOR_XML && currentNode.nodeType ===
|
|
1028
|
+
if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
|
|
1010
1029
|
_forceRemove(currentNode);
|
|
1011
1030
|
return true;
|
|
1012
1031
|
}
|
|
@@ -1053,7 +1072,7 @@ function createDOMPurify() {
|
|
|
1053
1072
|
}
|
|
1054
1073
|
|
|
1055
1074
|
/* Sanitize element content to be template-safe */
|
|
1056
|
-
if (SAFE_FOR_TEMPLATES && currentNode.nodeType ===
|
|
1075
|
+
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
|
|
1057
1076
|
/* Get the element's text content */
|
|
1058
1077
|
content = currentNode.textContent;
|
|
1059
1078
|
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
@@ -1083,7 +1102,7 @@ function createDOMPurify() {
|
|
|
1083
1102
|
// eslint-disable-next-line complexity
|
|
1084
1103
|
const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
1085
1104
|
/* Make sure attribute cannot clobber */
|
|
1086
|
-
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
1105
|
+
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement || value === '__depth' || value === '__removalCount')) {
|
|
1087
1106
|
return false;
|
|
1088
1107
|
}
|
|
1089
1108
|
|
|
@@ -1187,6 +1206,12 @@ function createDOMPurify() {
|
|
|
1187
1206
|
continue;
|
|
1188
1207
|
}
|
|
1189
1208
|
|
|
1209
|
+
/* Work around a security issue with comments inside attributes */
|
|
1210
|
+
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
|
|
1211
|
+
_removeAttribute(name, currentNode);
|
|
1212
|
+
continue;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1190
1215
|
/* Sanitize attribute content to be template-safe */
|
|
1191
1216
|
if (SAFE_FOR_TEMPLATES) {
|
|
1192
1217
|
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
@@ -1237,7 +1262,11 @@ function createDOMPurify() {
|
|
|
1237
1262
|
/* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
|
|
1238
1263
|
currentNode.setAttribute(name, value);
|
|
1239
1264
|
}
|
|
1240
|
-
|
|
1265
|
+
if (_isClobbered(currentNode)) {
|
|
1266
|
+
_forceRemove(currentNode);
|
|
1267
|
+
} else {
|
|
1268
|
+
arrayPop(DOMPurify.removed);
|
|
1269
|
+
}
|
|
1241
1270
|
} catch (_) {}
|
|
1242
1271
|
}
|
|
1243
1272
|
|
|
@@ -1264,22 +1293,26 @@ function createDOMPurify() {
|
|
|
1264
1293
|
if (_sanitizeElements(shadowNode)) {
|
|
1265
1294
|
continue;
|
|
1266
1295
|
}
|
|
1296
|
+
const parentNode = getParentNode(shadowNode);
|
|
1267
1297
|
|
|
1268
1298
|
/* Set the nesting depth of an element */
|
|
1269
|
-
if (shadowNode.nodeType ===
|
|
1270
|
-
if (
|
|
1299
|
+
if (shadowNode.nodeType === NODE_TYPE.element) {
|
|
1300
|
+
if (parentNode && parentNode.__depth) {
|
|
1271
1301
|
/*
|
|
1272
1302
|
We want the depth of the node in the original tree, which can
|
|
1273
1303
|
change when it's removed from its parent.
|
|
1274
1304
|
*/
|
|
1275
|
-
shadowNode.__depth = (shadowNode.__removalCount || 0) +
|
|
1305
|
+
shadowNode.__depth = (shadowNode.__removalCount || 0) + parentNode.__depth + 1;
|
|
1276
1306
|
} else {
|
|
1277
1307
|
shadowNode.__depth = 1;
|
|
1278
1308
|
}
|
|
1279
1309
|
}
|
|
1280
1310
|
|
|
1281
|
-
/*
|
|
1282
|
-
|
|
1311
|
+
/*
|
|
1312
|
+
* Remove an element if nested too deeply to avoid mXSS
|
|
1313
|
+
* or if the __depth might have been tampered with
|
|
1314
|
+
*/
|
|
1315
|
+
if (shadowNode.__depth >= MAX_NESTING_DEPTH || shadowNode.__depth < 0 || numberIsNaN(shadowNode.__depth)) {
|
|
1283
1316
|
_forceRemove(shadowNode);
|
|
1284
1317
|
}
|
|
1285
1318
|
|
|
@@ -1361,7 +1394,7 @@ function createDOMPurify() {
|
|
|
1361
1394
|
elements being stripped by the parser */
|
|
1362
1395
|
body = _initDocument('<!---->');
|
|
1363
1396
|
importedNode = body.ownerDocument.importNode(dirty, true);
|
|
1364
|
-
if (importedNode.nodeType ===
|
|
1397
|
+
if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {
|
|
1365
1398
|
/* Node is already a body, use as is */
|
|
1366
1399
|
body = importedNode;
|
|
1367
1400
|
} else if (importedNode.nodeName === 'HTML') {
|
|
@@ -1401,22 +1434,26 @@ function createDOMPurify() {
|
|
|
1401
1434
|
if (_sanitizeElements(currentNode)) {
|
|
1402
1435
|
continue;
|
|
1403
1436
|
}
|
|
1437
|
+
const parentNode = getParentNode(currentNode);
|
|
1404
1438
|
|
|
1405
1439
|
/* Set the nesting depth of an element */
|
|
1406
|
-
if (currentNode.nodeType ===
|
|
1407
|
-
if (
|
|
1440
|
+
if (currentNode.nodeType === NODE_TYPE.element) {
|
|
1441
|
+
if (parentNode && parentNode.__depth) {
|
|
1408
1442
|
/*
|
|
1409
1443
|
We want the depth of the node in the original tree, which can
|
|
1410
1444
|
change when it's removed from its parent.
|
|
1411
1445
|
*/
|
|
1412
|
-
currentNode.__depth = (currentNode.__removalCount || 0) +
|
|
1446
|
+
currentNode.__depth = (currentNode.__removalCount || 0) + parentNode.__depth + 1;
|
|
1413
1447
|
} else {
|
|
1414
1448
|
currentNode.__depth = 1;
|
|
1415
1449
|
}
|
|
1416
1450
|
}
|
|
1417
1451
|
|
|
1418
|
-
/*
|
|
1419
|
-
|
|
1452
|
+
/*
|
|
1453
|
+
* Remove an element if nested too deeply to avoid mXSS
|
|
1454
|
+
* or if the __depth might have been tampered with
|
|
1455
|
+
*/
|
|
1456
|
+
if (currentNode.__depth >= MAX_NESTING_DEPTH || currentNode.__depth < 0 || numberIsNaN(currentNode.__depth)) {
|
|
1420
1457
|
_forceRemove(currentNode);
|
|
1421
1458
|
}
|
|
1422
1459
|
|