dompurify 3.1.2 → 3.1.4
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 +4 -4
- package/dist/purify.cjs.js +54 -16
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.mjs +54 -16
- package/dist/purify.es.mjs.map +1 -1
- package/dist/purify.js +54 -16
- 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.4 | (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.4/LICENSE */
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
4
|
entries,
|
|
@@ -48,6 +48,10 @@ 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
|
+
function numberIsNaN(x) {
|
|
52
|
+
// eslint-disable-next-line unicorn/prefer-number-properties
|
|
53
|
+
return typeof x === 'number' && isNaN(x);
|
|
54
|
+
}
|
|
51
55
|
|
|
52
56
|
/**
|
|
53
57
|
* Creates a new function that calls the given function with a specified thisArg and arguments.
|
|
@@ -196,7 +200,7 @@ const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mgly
|
|
|
196
200
|
const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
|
|
197
201
|
const text = freeze(['#text']);
|
|
198
202
|
|
|
199
|
-
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']);
|
|
203
|
+
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', 'popover', 'popovertarget', 'popovertargetaction', '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']);
|
|
200
204
|
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']);
|
|
201
205
|
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']);
|
|
202
206
|
const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
@@ -231,6 +235,24 @@ var EXPRESSIONS = /*#__PURE__*/Object.freeze({
|
|
|
231
235
|
CUSTOM_ELEMENT: CUSTOM_ELEMENT
|
|
232
236
|
});
|
|
233
237
|
|
|
238
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
|
|
239
|
+
const NODE_TYPE = {
|
|
240
|
+
element: 1,
|
|
241
|
+
attribute: 2,
|
|
242
|
+
text: 3,
|
|
243
|
+
cdataSection: 4,
|
|
244
|
+
entityReference: 5,
|
|
245
|
+
// Deprecated
|
|
246
|
+
entityNode: 6,
|
|
247
|
+
// Deprecated
|
|
248
|
+
progressingInstruction: 7,
|
|
249
|
+
comment: 8,
|
|
250
|
+
document: 9,
|
|
251
|
+
documentType: 10,
|
|
252
|
+
documentFragment: 11,
|
|
253
|
+
notation: 12 // Deprecated
|
|
254
|
+
};
|
|
255
|
+
|
|
234
256
|
const getGlobal = function getGlobal() {
|
|
235
257
|
return typeof window === 'undefined' ? null : window;
|
|
236
258
|
};
|
|
@@ -282,14 +304,14 @@ function createDOMPurify() {
|
|
|
282
304
|
* Version label, exposed for easier checks
|
|
283
305
|
* if DOMPurify is up to date or not
|
|
284
306
|
*/
|
|
285
|
-
DOMPurify.version = '3.1.
|
|
307
|
+
DOMPurify.version = '3.1.4';
|
|
286
308
|
|
|
287
309
|
/**
|
|
288
310
|
* Array of elements that DOMPurify removed during sanitation.
|
|
289
311
|
* Empty if nothing was removed.
|
|
290
312
|
*/
|
|
291
313
|
DOMPurify.removed = [];
|
|
292
|
-
if (!window || !window.document || window.document.nodeType !==
|
|
314
|
+
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document) {
|
|
293
315
|
// Not running in a browser, provide a factory function
|
|
294
316
|
// so that you can pass your own Window
|
|
295
317
|
DOMPurify.isSupported = false;
|
|
@@ -1000,13 +1022,13 @@ function createDOMPurify() {
|
|
|
1000
1022
|
}
|
|
1001
1023
|
|
|
1002
1024
|
/* Remove any ocurrence of processing instructions */
|
|
1003
|
-
if (currentNode.nodeType ===
|
|
1025
|
+
if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
|
|
1004
1026
|
_forceRemove(currentNode);
|
|
1005
1027
|
return true;
|
|
1006
1028
|
}
|
|
1007
1029
|
|
|
1008
1030
|
/* Remove any kind of possibly harmful comments */
|
|
1009
|
-
if (SAFE_FOR_XML && currentNode.nodeType ===
|
|
1031
|
+
if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
|
|
1010
1032
|
_forceRemove(currentNode);
|
|
1011
1033
|
return true;
|
|
1012
1034
|
}
|
|
@@ -1053,7 +1075,7 @@ function createDOMPurify() {
|
|
|
1053
1075
|
}
|
|
1054
1076
|
|
|
1055
1077
|
/* Sanitize element content to be template-safe */
|
|
1056
|
-
if (SAFE_FOR_TEMPLATES && currentNode.nodeType ===
|
|
1078
|
+
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
|
|
1057
1079
|
/* Get the element's text content */
|
|
1058
1080
|
content = currentNode.textContent;
|
|
1059
1081
|
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
@@ -1083,7 +1105,7 @@ function createDOMPurify() {
|
|
|
1083
1105
|
// eslint-disable-next-line complexity
|
|
1084
1106
|
const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
1085
1107
|
/* Make sure attribute cannot clobber */
|
|
1086
|
-
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
1108
|
+
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement || value === '__depth' || value === '__removalCount')) {
|
|
1087
1109
|
return false;
|
|
1088
1110
|
}
|
|
1089
1111
|
|
|
@@ -1187,6 +1209,12 @@ function createDOMPurify() {
|
|
|
1187
1209
|
continue;
|
|
1188
1210
|
}
|
|
1189
1211
|
|
|
1212
|
+
/* Work around a security issue with comments inside attributes */
|
|
1213
|
+
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
|
|
1214
|
+
_removeAttribute(name, currentNode);
|
|
1215
|
+
continue;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1190
1218
|
/* Sanitize attribute content to be template-safe */
|
|
1191
1219
|
if (SAFE_FOR_TEMPLATES) {
|
|
1192
1220
|
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
@@ -1237,7 +1265,11 @@ function createDOMPurify() {
|
|
|
1237
1265
|
/* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
|
|
1238
1266
|
currentNode.setAttribute(name, value);
|
|
1239
1267
|
}
|
|
1240
|
-
|
|
1268
|
+
if (_isClobbered(currentNode)) {
|
|
1269
|
+
_forceRemove(currentNode);
|
|
1270
|
+
} else {
|
|
1271
|
+
arrayPop(DOMPurify.removed);
|
|
1272
|
+
}
|
|
1241
1273
|
} catch (_) {}
|
|
1242
1274
|
}
|
|
1243
1275
|
|
|
@@ -1267,7 +1299,7 @@ function createDOMPurify() {
|
|
|
1267
1299
|
const parentNode = getParentNode(shadowNode);
|
|
1268
1300
|
|
|
1269
1301
|
/* Set the nesting depth of an element */
|
|
1270
|
-
if (shadowNode.nodeType ===
|
|
1302
|
+
if (shadowNode.nodeType === NODE_TYPE.element) {
|
|
1271
1303
|
if (parentNode && parentNode.__depth) {
|
|
1272
1304
|
/*
|
|
1273
1305
|
We want the depth of the node in the original tree, which can
|
|
@@ -1279,8 +1311,11 @@ function createDOMPurify() {
|
|
|
1279
1311
|
}
|
|
1280
1312
|
}
|
|
1281
1313
|
|
|
1282
|
-
/*
|
|
1283
|
-
|
|
1314
|
+
/*
|
|
1315
|
+
* Remove an element if nested too deeply to avoid mXSS
|
|
1316
|
+
* or if the __depth might have been tampered with
|
|
1317
|
+
*/
|
|
1318
|
+
if (shadowNode.__depth >= MAX_NESTING_DEPTH || shadowNode.__depth < 0 || numberIsNaN(shadowNode.__depth)) {
|
|
1284
1319
|
_forceRemove(shadowNode);
|
|
1285
1320
|
}
|
|
1286
1321
|
|
|
@@ -1362,7 +1397,7 @@ function createDOMPurify() {
|
|
|
1362
1397
|
elements being stripped by the parser */
|
|
1363
1398
|
body = _initDocument('<!---->');
|
|
1364
1399
|
importedNode = body.ownerDocument.importNode(dirty, true);
|
|
1365
|
-
if (importedNode.nodeType ===
|
|
1400
|
+
if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {
|
|
1366
1401
|
/* Node is already a body, use as is */
|
|
1367
1402
|
body = importedNode;
|
|
1368
1403
|
} else if (importedNode.nodeName === 'HTML') {
|
|
@@ -1405,7 +1440,7 @@ function createDOMPurify() {
|
|
|
1405
1440
|
const parentNode = getParentNode(currentNode);
|
|
1406
1441
|
|
|
1407
1442
|
/* Set the nesting depth of an element */
|
|
1408
|
-
if (currentNode.nodeType ===
|
|
1443
|
+
if (currentNode.nodeType === NODE_TYPE.element) {
|
|
1409
1444
|
if (parentNode && parentNode.__depth) {
|
|
1410
1445
|
/*
|
|
1411
1446
|
We want the depth of the node in the original tree, which can
|
|
@@ -1417,8 +1452,11 @@ function createDOMPurify() {
|
|
|
1417
1452
|
}
|
|
1418
1453
|
}
|
|
1419
1454
|
|
|
1420
|
-
/*
|
|
1421
|
-
|
|
1455
|
+
/*
|
|
1456
|
+
* Remove an element if nested too deeply to avoid mXSS
|
|
1457
|
+
* or if the __depth might have been tampered with
|
|
1458
|
+
*/
|
|
1459
|
+
if (currentNode.__depth >= MAX_NESTING_DEPTH || currentNode.__depth < 0 || numberIsNaN(currentNode.__depth)) {
|
|
1422
1460
|
_forceRemove(currentNode);
|
|
1423
1461
|
}
|
|
1424
1462
|
|