dompurify 3.0.11 → 3.1.1
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 +1 -1
- package/README.md +21 -6
- package/dist/purify.cjs.js +64 -5
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.mjs +64 -5
- package/dist/purify.es.mjs.map +1 -1
- package/dist/purify.js +64 -5
- 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.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @license DOMPurify 3.
|
|
1
|
+
/*! @license DOMPurify 3.1.1 | (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.1/LICENSE */
|
|
2
2
|
|
|
3
3
|
(function (global, factory) {
|
|
4
4
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
@@ -202,7 +202,7 @@
|
|
|
202
202
|
const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
|
|
203
203
|
const text = freeze(['#text']);
|
|
204
204
|
|
|
205
|
-
const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns', 'slot']);
|
|
205
|
+
const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
|
|
206
206
|
const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
|
|
207
207
|
const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
|
|
208
208
|
const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
@@ -288,7 +288,7 @@
|
|
|
288
288
|
* Version label, exposed for easier checks
|
|
289
289
|
* if DOMPurify is up to date or not
|
|
290
290
|
*/
|
|
291
|
-
DOMPurify.version = '3.
|
|
291
|
+
DOMPurify.version = '3.1.1';
|
|
292
292
|
|
|
293
293
|
/**
|
|
294
294
|
* Array of elements that DOMPurify removed during sanitation.
|
|
@@ -430,6 +430,11 @@
|
|
|
430
430
|
*/
|
|
431
431
|
let SAFE_FOR_TEMPLATES = false;
|
|
432
432
|
|
|
433
|
+
/* Output should be safe even for XML used within HTML and alike.
|
|
434
|
+
* This means, DOMPurify removes comments when containing risky content.
|
|
435
|
+
*/
|
|
436
|
+
let SAFE_FOR_XML = true;
|
|
437
|
+
|
|
433
438
|
/* Decide if document with <html>... should be returned */
|
|
434
439
|
let WHOLE_DOCUMENT = false;
|
|
435
440
|
|
|
@@ -516,6 +521,9 @@
|
|
|
516
521
|
/* Keep a reference to config to pass to hooks */
|
|
517
522
|
let CONFIG = null;
|
|
518
523
|
|
|
524
|
+
/* Specify the maximum element nesting depth to prevent mXSS */
|
|
525
|
+
const MAX_NESTING_DEPTH = 255;
|
|
526
|
+
|
|
519
527
|
/* Ideally, do not touch anything below this line */
|
|
520
528
|
/* ______________________________________________ */
|
|
521
529
|
|
|
@@ -577,6 +585,7 @@
|
|
|
577
585
|
ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
|
|
578
586
|
ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true
|
|
579
587
|
SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
|
|
588
|
+
SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true
|
|
580
589
|
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
|
|
581
590
|
RETURN_DOM = cfg.RETURN_DOM || false; // Default false
|
|
582
591
|
RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
|
|
@@ -925,7 +934,11 @@
|
|
|
925
934
|
* @return {Boolean} true if clobbered, false if safe
|
|
926
935
|
*/
|
|
927
936
|
const _isClobbered = function _isClobbered(elm) {
|
|
928
|
-
return elm instanceof HTMLFormElement && (
|
|
937
|
+
return elm instanceof HTMLFormElement && (
|
|
938
|
+
// eslint-disable-next-line unicorn/no-typeof-undefined
|
|
939
|
+
typeof elm.__depth !== 'undefined' && typeof elm.__depth !== 'number' ||
|
|
940
|
+
// eslint-disable-next-line unicorn/no-typeof-undefined
|
|
941
|
+
typeof elm.__removalCount !== 'undefined' && typeof elm.__removalCount !== 'number' || typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function' || typeof elm.hasChildNodes !== 'function');
|
|
929
942
|
};
|
|
930
943
|
|
|
931
944
|
/**
|
|
@@ -998,6 +1011,12 @@
|
|
|
998
1011
|
return true;
|
|
999
1012
|
}
|
|
1000
1013
|
|
|
1014
|
+
/* Remove any kind of possibly harmful comments */
|
|
1015
|
+
if (SAFE_FOR_XML && currentNode.nodeType === 8 && regExpTest(/<[/\w]/g, currentNode.data)) {
|
|
1016
|
+
_forceRemove(currentNode);
|
|
1017
|
+
return true;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1001
1020
|
/* Remove element if anything forbids its presence */
|
|
1002
1021
|
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
1003
1022
|
/* Check if we have a custom element to handle */
|
|
@@ -1017,7 +1036,9 @@
|
|
|
1017
1036
|
if (childNodes && parentNode) {
|
|
1018
1037
|
const childCount = childNodes.length;
|
|
1019
1038
|
for (let i = childCount - 1; i >= 0; --i) {
|
|
1020
|
-
|
|
1039
|
+
const childClone = cloneNode(childNodes[i], true);
|
|
1040
|
+
childClone.__removalCount = (currentNode.__removalCount || 0) + 1;
|
|
1041
|
+
parentNode.insertBefore(childClone, getNextSibling(currentNode));
|
|
1021
1042
|
}
|
|
1022
1043
|
}
|
|
1023
1044
|
}
|
|
@@ -1250,8 +1271,27 @@
|
|
|
1250
1271
|
continue;
|
|
1251
1272
|
}
|
|
1252
1273
|
|
|
1274
|
+
/* Set the nesting depth of an element */
|
|
1275
|
+
if (shadowNode.nodeType === 1) {
|
|
1276
|
+
if (shadowNode.parentNode && shadowNode.parentNode.__depth) {
|
|
1277
|
+
/*
|
|
1278
|
+
We want the depth of the node in the original tree, which can
|
|
1279
|
+
change when it's removed from its parent.
|
|
1280
|
+
*/
|
|
1281
|
+
shadowNode.__depth = (shadowNode.__removalCount || 0) + shadowNode.parentNode.__depth + 1;
|
|
1282
|
+
} else {
|
|
1283
|
+
shadowNode.__depth = 1;
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
/* Remove an element if nested too deeply to avoid mXSS */
|
|
1288
|
+
if (shadowNode.__depth >= MAX_NESTING_DEPTH) {
|
|
1289
|
+
_forceRemove(shadowNode);
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1253
1292
|
/* Deep shadow DOM detected */
|
|
1254
1293
|
if (shadowNode.content instanceof DocumentFragment) {
|
|
1294
|
+
shadowNode.content.__depth = shadowNode.__depth;
|
|
1255
1295
|
_sanitizeShadowDOM(shadowNode.content);
|
|
1256
1296
|
}
|
|
1257
1297
|
|
|
@@ -1368,8 +1408,27 @@
|
|
|
1368
1408
|
continue;
|
|
1369
1409
|
}
|
|
1370
1410
|
|
|
1411
|
+
/* Set the nesting depth of an element */
|
|
1412
|
+
if (currentNode.nodeType === 1) {
|
|
1413
|
+
if (currentNode.parentNode && currentNode.parentNode.__depth) {
|
|
1414
|
+
/*
|
|
1415
|
+
We want the depth of the node in the original tree, which can
|
|
1416
|
+
change when it's removed from its parent.
|
|
1417
|
+
*/
|
|
1418
|
+
currentNode.__depth = (currentNode.__removalCount || 0) + currentNode.parentNode.__depth + 1;
|
|
1419
|
+
} else {
|
|
1420
|
+
currentNode.__depth = 1;
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
/* Remove an element if nested too deeply to avoid mXSS */
|
|
1425
|
+
if (currentNode.__depth >= MAX_NESTING_DEPTH) {
|
|
1426
|
+
_forceRemove(currentNode);
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1371
1429
|
/* Shadow DOM detected, sanitize it */
|
|
1372
1430
|
if (currentNode.content instanceof DocumentFragment) {
|
|
1431
|
+
currentNode.content.__depth = currentNode.__depth;
|
|
1373
1432
|
_sanitizeShadowDOM(currentNode.content);
|
|
1374
1433
|
}
|
|
1375
1434
|
|