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 CHANGED
@@ -6,11 +6,11 @@
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.1.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.1.4**.
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
 
13
- **Note that [DOMPurify v2.5.2](https://github.com/cure53/DOMPurify/releases/tag/2.5.2) is the latest version supporting MSIE. For important security updates compatible with MSIE, please use the [2.x branch](https://github.com/cure53/DOMPurify/tree/2.x).**
13
+ **Note that [DOMPurify v2.5.4](https://github.com/cure53/DOMPurify/releases/tag/2.5.4) is the latest 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
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
 
@@ -45,7 +45,7 @@ const clean = DOMPurify.sanitize(dirty);
45
45
  Or maybe this, if you love working with Angular or alike:
46
46
 
47
47
  ```js
48
- import * as DOMPurify from 'dompurify';
48
+ import DOMPurify from 'dompurify';
49
49
 
50
50
  const clean = DOMPurify.sanitize('<b>hello there</b>');
51
51
  ```
@@ -424,7 +424,7 @@ Feature releases will not be announced to this list.
424
424
 
425
425
  Many people helped and help DOMPurify become what it is and need to be acknowledged here!
426
426
 
427
- [icesfont ❤️](https://github.com/icesfont) [dcramer 💸](https://github.com/dcramer), [JGraph 💸](https://github.com/jgraph), [baekilda 💸](https://github.com/baekilda), [Healthchecks 💸](https://github.com/healthchecks), [Sentry 💸](https://github.com/getsentry), [jarrodldavis 💸](https://github.com/jarrodldavis), [CynegeticIO](https://github.com/CynegeticIO), [ssi02014 ❤️](https://github.com/ssi02014), [kevin_mizu](https://twitter.com/kevin_mizu), [GrantGryczan](https://github.com/GrantGryczan), [Lowdefy](https://twitter.com/lowdefy), [granlem](https://twitter.com/MaximeVeit), [oreoshake](https://github.com/oreoshake), [tdeekens ❤️](https://github.com/tdeekens), [peernohell ❤️](https://github.com/peernohell), [is2ei](https://github.com/is2ei), [SoheilKhodayari](https://github.com/SoheilKhodayari), [franktopel](https://github.com/franktopel), [NateScarlet](https://github.com/NateScarlet), [neilj](https://github.com/neilj), [fhemberger](https://github.com/fhemberger), [Joris-van-der-Wel](https://github.com/Joris-van-der-Wel), [ydaniv](https://github.com/ydaniv), [terjanq](https://twitter.com/terjanq), [filedescriptor](https://github.com/filedescriptor), [ConradIrwin](https://github.com/ConradIrwin), [gibson042](https://github.com/gibson042), [choumx](https://github.com/choumx), [0xSobky](https://github.com/0xSobky), [styfle](https://github.com/styfle), [koto](https://github.com/koto), [tlau88](https://github.com/tlau88), [strugee](https://github.com/strugee), [oparoz](https://github.com/oparoz), [mathiasbynens](https://github.com/mathiasbynens), [edg2s](https://github.com/edg2s), [dnkolegov](https://github.com/dnkolegov), [dhardtke](https://github.com/dhardtke), [wirehead](https://github.com/wirehead), [thorn0](https://github.com/thorn0), [styu](https://github.com/styu), [mozfreddyb](https://github.com/mozfreddyb), [mikesamuel](https://github.com/mikesamuel), [jorangreef](https://github.com/jorangreef), [jimmyhchan](https://github.com/jimmyhchan), [jameydeorio](https://github.com/jameydeorio), [jameskraus](https://github.com/jameskraus), [hyderali](https://github.com/hyderali), [hansottowirtz](https://github.com/hansottowirtz), [hackvertor](https://github.com/hackvertor), [freddyb](https://github.com/freddyb), [flavorjones](https://github.com/flavorjones), [djfarrelly](https://github.com/djfarrelly), [devd](https://github.com/devd), [camerondunford](https://github.com/camerondunford), [buu700](https://github.com/buu700), [buildog](https://github.com/buildog), [alabiaga](https://github.com/alabiaga), [Vector919](https://github.com/Vector919), [Robbert](https://github.com/Robbert), [GreLI](https://github.com/GreLI), [FuzzySockets](https://github.com/FuzzySockets), [ArtemBernatskyy](https://github.com/ArtemBernatskyy), [@garethheyes](https://twitter.com/garethheyes), [@shafigullin](https://twitter.com/shafigullin), [@mmrupp](https://twitter.com/mmrupp), [@irsdl](https://twitter.com/irsdl),[ShikariSenpai](https://github.com/ShikariSenpai), [ansjdnakjdnajkd](https://github.com/ansjdnakjdnajkd), [@asutherland](https://twitter.com/asutherland), [@mathias](https://twitter.com/mathias), [@cgvwzq](https://twitter.com/cgvwzq), [@robbertatwork](https://twitter.com/robbertatwork), [@giutro](https://twitter.com/giutro), [@CmdEngineer\_](https://twitter.com/CmdEngineer_), [@avr4mit](https://twitter.com/avr4mit) and especially [@securitymb ❤️](https://twitter.com/securitymb) & [@masatokinugawa ❤️](https://twitter.com/masatokinugawa)
427
+ [hash_kitten ❤️](https://twitter.com/hash_kitten), [kevin_mizu ❤️](https://twitter.com/kevin_mizu), [icesfont ❤️](https://github.com/icesfont) [dcramer 💸](https://github.com/dcramer), [JGraph 💸](https://github.com/jgraph), [baekilda 💸](https://github.com/baekilda), [Healthchecks 💸](https://github.com/healthchecks), [Sentry 💸](https://github.com/getsentry), [jarrodldavis 💸](https://github.com/jarrodldavis), [CynegeticIO](https://github.com/CynegeticIO), [ssi02014 ❤️](https://github.com/ssi02014), [GrantGryczan](https://github.com/GrantGryczan), [Lowdefy](https://twitter.com/lowdefy), [granlem](https://twitter.com/MaximeVeit), [oreoshake](https://github.com/oreoshake), [tdeekens ❤️](https://github.com/tdeekens), [peernohell ❤️](https://github.com/peernohell), [is2ei](https://github.com/is2ei), [SoheilKhodayari](https://github.com/SoheilKhodayari), [franktopel](https://github.com/franktopel), [NateScarlet](https://github.com/NateScarlet), [neilj](https://github.com/neilj), [fhemberger](https://github.com/fhemberger), [Joris-van-der-Wel](https://github.com/Joris-van-der-Wel), [ydaniv](https://github.com/ydaniv), [terjanq](https://twitter.com/terjanq), [filedescriptor](https://github.com/filedescriptor), [ConradIrwin](https://github.com/ConradIrwin), [gibson042](https://github.com/gibson042), [choumx](https://github.com/choumx), [0xSobky](https://github.com/0xSobky), [styfle](https://github.com/styfle), [koto](https://github.com/koto), [tlau88](https://github.com/tlau88), [strugee](https://github.com/strugee), [oparoz](https://github.com/oparoz), [mathiasbynens](https://github.com/mathiasbynens), [edg2s](https://github.com/edg2s), [dnkolegov](https://github.com/dnkolegov), [dhardtke](https://github.com/dhardtke), [wirehead](https://github.com/wirehead), [thorn0](https://github.com/thorn0), [styu](https://github.com/styu), [mozfreddyb](https://github.com/mozfreddyb), [mikesamuel](https://github.com/mikesamuel), [jorangreef](https://github.com/jorangreef), [jimmyhchan](https://github.com/jimmyhchan), [jameydeorio](https://github.com/jameydeorio), [jameskraus](https://github.com/jameskraus), [hyderali](https://github.com/hyderali), [hansottowirtz](https://github.com/hansottowirtz), [hackvertor](https://github.com/hackvertor), [freddyb](https://github.com/freddyb), [flavorjones](https://github.com/flavorjones), [djfarrelly](https://github.com/djfarrelly), [devd](https://github.com/devd), [camerondunford](https://github.com/camerondunford), [buu700](https://github.com/buu700), [buildog](https://github.com/buildog), [alabiaga](https://github.com/alabiaga), [Vector919](https://github.com/Vector919), [Robbert](https://github.com/Robbert), [GreLI](https://github.com/GreLI), [FuzzySockets](https://github.com/FuzzySockets), [ArtemBernatskyy](https://github.com/ArtemBernatskyy), [@garethheyes](https://twitter.com/garethheyes), [@shafigullin](https://twitter.com/shafigullin), [@mmrupp](https://twitter.com/mmrupp), [@irsdl](https://twitter.com/irsdl),[ShikariSenpai](https://github.com/ShikariSenpai), [ansjdnakjdnajkd](https://github.com/ansjdnakjdnajkd), [@asutherland](https://twitter.com/asutherland), [@mathias](https://twitter.com/mathias), [@cgvwzq](https://twitter.com/cgvwzq), [@robbertatwork](https://twitter.com/robbertatwork), [@giutro](https://twitter.com/giutro), [@CmdEngineer\_](https://twitter.com/CmdEngineer_), [@avr4mit](https://twitter.com/avr4mit) and especially [@securitymb ❤️](https://twitter.com/securitymb) & [@masatokinugawa ❤️](https://twitter.com/masatokinugawa)
428
428
 
429
429
  ## Testing powered by
430
430
 
@@ -1,4 +1,4 @@
1
- /*! @license DOMPurify 3.1.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.1.2/LICENSE */
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
  'use strict';
4
4
 
@@ -50,6 +50,10 @@ const stringTrim = unapply(String.prototype.trim);
50
50
  const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
51
51
  const regExpTest = unapply(RegExp.prototype.test);
52
52
  const typeErrorCreate = unconstruct(TypeError);
53
+ function numberIsNaN(x) {
54
+ // eslint-disable-next-line unicorn/prefer-number-properties
55
+ return typeof x === 'number' && isNaN(x);
56
+ }
53
57
 
54
58
  /**
55
59
  * Creates a new function that calls the given function with a specified thisArg and arguments.
@@ -198,7 +202,7 @@ const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mgly
198
202
  const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
199
203
  const text = freeze(['#text']);
200
204
 
201
- 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']);
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', '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']);
202
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']);
203
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']);
204
208
  const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
@@ -233,6 +237,24 @@ var EXPRESSIONS = /*#__PURE__*/Object.freeze({
233
237
  CUSTOM_ELEMENT: CUSTOM_ELEMENT
234
238
  });
235
239
 
240
+ // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
241
+ const NODE_TYPE = {
242
+ element: 1,
243
+ attribute: 2,
244
+ text: 3,
245
+ cdataSection: 4,
246
+ entityReference: 5,
247
+ // Deprecated
248
+ entityNode: 6,
249
+ // Deprecated
250
+ progressingInstruction: 7,
251
+ comment: 8,
252
+ document: 9,
253
+ documentType: 10,
254
+ documentFragment: 11,
255
+ notation: 12 // Deprecated
256
+ };
257
+
236
258
  const getGlobal = function getGlobal() {
237
259
  return typeof window === 'undefined' ? null : window;
238
260
  };
@@ -284,14 +306,14 @@ function createDOMPurify() {
284
306
  * Version label, exposed for easier checks
285
307
  * if DOMPurify is up to date or not
286
308
  */
287
- DOMPurify.version = '3.1.2';
309
+ DOMPurify.version = '3.1.4';
288
310
 
289
311
  /**
290
312
  * Array of elements that DOMPurify removed during sanitation.
291
313
  * Empty if nothing was removed.
292
314
  */
293
315
  DOMPurify.removed = [];
294
- if (!window || !window.document || window.document.nodeType !== 9) {
316
+ if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document) {
295
317
  // Not running in a browser, provide a factory function
296
318
  // so that you can pass your own Window
297
319
  DOMPurify.isSupported = false;
@@ -1002,13 +1024,13 @@ function createDOMPurify() {
1002
1024
  }
1003
1025
 
1004
1026
  /* Remove any ocurrence of processing instructions */
1005
- if (currentNode.nodeType === 7) {
1027
+ if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
1006
1028
  _forceRemove(currentNode);
1007
1029
  return true;
1008
1030
  }
1009
1031
 
1010
1032
  /* Remove any kind of possibly harmful comments */
1011
- if (SAFE_FOR_XML && currentNode.nodeType === 8 && regExpTest(/<[/\w]/g, currentNode.data)) {
1033
+ if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
1012
1034
  _forceRemove(currentNode);
1013
1035
  return true;
1014
1036
  }
@@ -1055,7 +1077,7 @@ function createDOMPurify() {
1055
1077
  }
1056
1078
 
1057
1079
  /* Sanitize element content to be template-safe */
1058
- if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
1080
+ if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
1059
1081
  /* Get the element's text content */
1060
1082
  content = currentNode.textContent;
1061
1083
  arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
@@ -1085,7 +1107,7 @@ function createDOMPurify() {
1085
1107
  // eslint-disable-next-line complexity
1086
1108
  const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
1087
1109
  /* Make sure attribute cannot clobber */
1088
- if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
1110
+ if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement || value === '__depth' || value === '__removalCount')) {
1089
1111
  return false;
1090
1112
  }
1091
1113
 
@@ -1189,6 +1211,12 @@ function createDOMPurify() {
1189
1211
  continue;
1190
1212
  }
1191
1213
 
1214
+ /* Work around a security issue with comments inside attributes */
1215
+ if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
1216
+ _removeAttribute(name, currentNode);
1217
+ continue;
1218
+ }
1219
+
1192
1220
  /* Sanitize attribute content to be template-safe */
1193
1221
  if (SAFE_FOR_TEMPLATES) {
1194
1222
  arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
@@ -1239,7 +1267,11 @@ function createDOMPurify() {
1239
1267
  /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
1240
1268
  currentNode.setAttribute(name, value);
1241
1269
  }
1242
- arrayPop(DOMPurify.removed);
1270
+ if (_isClobbered(currentNode)) {
1271
+ _forceRemove(currentNode);
1272
+ } else {
1273
+ arrayPop(DOMPurify.removed);
1274
+ }
1243
1275
  } catch (_) {}
1244
1276
  }
1245
1277
 
@@ -1269,7 +1301,7 @@ function createDOMPurify() {
1269
1301
  const parentNode = getParentNode(shadowNode);
1270
1302
 
1271
1303
  /* Set the nesting depth of an element */
1272
- if (shadowNode.nodeType === 1) {
1304
+ if (shadowNode.nodeType === NODE_TYPE.element) {
1273
1305
  if (parentNode && parentNode.__depth) {
1274
1306
  /*
1275
1307
  We want the depth of the node in the original tree, which can
@@ -1281,8 +1313,11 @@ function createDOMPurify() {
1281
1313
  }
1282
1314
  }
1283
1315
 
1284
- /* Remove an element if nested too deeply to avoid mXSS */
1285
- if (shadowNode.__depth >= MAX_NESTING_DEPTH) {
1316
+ /*
1317
+ * Remove an element if nested too deeply to avoid mXSS
1318
+ * or if the __depth might have been tampered with
1319
+ */
1320
+ if (shadowNode.__depth >= MAX_NESTING_DEPTH || shadowNode.__depth < 0 || numberIsNaN(shadowNode.__depth)) {
1286
1321
  _forceRemove(shadowNode);
1287
1322
  }
1288
1323
 
@@ -1364,7 +1399,7 @@ function createDOMPurify() {
1364
1399
  elements being stripped by the parser */
1365
1400
  body = _initDocument('<!---->');
1366
1401
  importedNode = body.ownerDocument.importNode(dirty, true);
1367
- if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {
1402
+ if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {
1368
1403
  /* Node is already a body, use as is */
1369
1404
  body = importedNode;
1370
1405
  } else if (importedNode.nodeName === 'HTML') {
@@ -1407,7 +1442,7 @@ function createDOMPurify() {
1407
1442
  const parentNode = getParentNode(currentNode);
1408
1443
 
1409
1444
  /* Set the nesting depth of an element */
1410
- if (currentNode.nodeType === 1) {
1445
+ if (currentNode.nodeType === NODE_TYPE.element) {
1411
1446
  if (parentNode && parentNode.__depth) {
1412
1447
  /*
1413
1448
  We want the depth of the node in the original tree, which can
@@ -1419,8 +1454,11 @@ function createDOMPurify() {
1419
1454
  }
1420
1455
  }
1421
1456
 
1422
- /* Remove an element if nested too deeply to avoid mXSS */
1423
- if (currentNode.__depth >= MAX_NESTING_DEPTH) {
1457
+ /*
1458
+ * Remove an element if nested too deeply to avoid mXSS
1459
+ * or if the __depth might have been tampered with
1460
+ */
1461
+ if (currentNode.__depth >= MAX_NESTING_DEPTH || currentNode.__depth < 0 || numberIsNaN(currentNode.__depth)) {
1424
1462
  _forceRemove(currentNode);
1425
1463
  }
1426
1464