dompurify 3.1.2 → 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 +50 -15
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.mjs +50 -15
- package/dist/purify.es.mjs.map +1 -1
- package/dist/purify.js +50 -15
- 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/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.
|
|
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.3**.
|
|
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.
|
|
13
|
+
**Note that [DOMPurify v2.5.3](https://github.com/cure53/DOMPurify/releases/tag/2.5.3) 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
|
|
|
@@ -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), [
|
|
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
|
|
package/dist/purify.cjs.js
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
|
'use strict';
|
|
4
4
|
|
|
@@ -50,6 +50,7 @@ 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
|
+
const numberIsNaN = unapply(Number.isNaN);
|
|
53
54
|
|
|
54
55
|
/**
|
|
55
56
|
* Creates a new function that calls the given function with a specified thisArg and arguments.
|
|
@@ -233,6 +234,24 @@ var EXPRESSIONS = /*#__PURE__*/Object.freeze({
|
|
|
233
234
|
CUSTOM_ELEMENT: CUSTOM_ELEMENT
|
|
234
235
|
});
|
|
235
236
|
|
|
237
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
|
|
238
|
+
const NODE_TYPE = {
|
|
239
|
+
element: 1,
|
|
240
|
+
attribute: 2,
|
|
241
|
+
text: 3,
|
|
242
|
+
cdataSection: 4,
|
|
243
|
+
entityReference: 5,
|
|
244
|
+
// Deprecated
|
|
245
|
+
entityNode: 6,
|
|
246
|
+
// Deprecated
|
|
247
|
+
progressingInstruction: 7,
|
|
248
|
+
comment: 8,
|
|
249
|
+
document: 9,
|
|
250
|
+
documentType: 10,
|
|
251
|
+
documentFragment: 11,
|
|
252
|
+
notation: 12 // Deprecated
|
|
253
|
+
};
|
|
254
|
+
|
|
236
255
|
const getGlobal = function getGlobal() {
|
|
237
256
|
return typeof window === 'undefined' ? null : window;
|
|
238
257
|
};
|
|
@@ -284,14 +303,14 @@ function createDOMPurify() {
|
|
|
284
303
|
* Version label, exposed for easier checks
|
|
285
304
|
* if DOMPurify is up to date or not
|
|
286
305
|
*/
|
|
287
|
-
DOMPurify.version = '3.1.
|
|
306
|
+
DOMPurify.version = '3.1.3';
|
|
288
307
|
|
|
289
308
|
/**
|
|
290
309
|
* Array of elements that DOMPurify removed during sanitation.
|
|
291
310
|
* Empty if nothing was removed.
|
|
292
311
|
*/
|
|
293
312
|
DOMPurify.removed = [];
|
|
294
|
-
if (!window || !window.document || window.document.nodeType !==
|
|
313
|
+
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document) {
|
|
295
314
|
// Not running in a browser, provide a factory function
|
|
296
315
|
// so that you can pass your own Window
|
|
297
316
|
DOMPurify.isSupported = false;
|
|
@@ -1002,13 +1021,13 @@ function createDOMPurify() {
|
|
|
1002
1021
|
}
|
|
1003
1022
|
|
|
1004
1023
|
/* Remove any ocurrence of processing instructions */
|
|
1005
|
-
if (currentNode.nodeType ===
|
|
1024
|
+
if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
|
|
1006
1025
|
_forceRemove(currentNode);
|
|
1007
1026
|
return true;
|
|
1008
1027
|
}
|
|
1009
1028
|
|
|
1010
1029
|
/* Remove any kind of possibly harmful comments */
|
|
1011
|
-
if (SAFE_FOR_XML && currentNode.nodeType ===
|
|
1030
|
+
if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
|
|
1012
1031
|
_forceRemove(currentNode);
|
|
1013
1032
|
return true;
|
|
1014
1033
|
}
|
|
@@ -1055,7 +1074,7 @@ function createDOMPurify() {
|
|
|
1055
1074
|
}
|
|
1056
1075
|
|
|
1057
1076
|
/* Sanitize element content to be template-safe */
|
|
1058
|
-
if (SAFE_FOR_TEMPLATES && currentNode.nodeType ===
|
|
1077
|
+
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
|
|
1059
1078
|
/* Get the element's text content */
|
|
1060
1079
|
content = currentNode.textContent;
|
|
1061
1080
|
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
@@ -1085,7 +1104,7 @@ function createDOMPurify() {
|
|
|
1085
1104
|
// eslint-disable-next-line complexity
|
|
1086
1105
|
const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
1087
1106
|
/* Make sure attribute cannot clobber */
|
|
1088
|
-
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
1107
|
+
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement || value === '__depth' || value === '__removalCount')) {
|
|
1089
1108
|
return false;
|
|
1090
1109
|
}
|
|
1091
1110
|
|
|
@@ -1189,6 +1208,12 @@ function createDOMPurify() {
|
|
|
1189
1208
|
continue;
|
|
1190
1209
|
}
|
|
1191
1210
|
|
|
1211
|
+
/* Work around a security issue with comments inside attributes */
|
|
1212
|
+
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
|
|
1213
|
+
_removeAttribute(name, currentNode);
|
|
1214
|
+
continue;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1192
1217
|
/* Sanitize attribute content to be template-safe */
|
|
1193
1218
|
if (SAFE_FOR_TEMPLATES) {
|
|
1194
1219
|
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
@@ -1239,7 +1264,11 @@ function createDOMPurify() {
|
|
|
1239
1264
|
/* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
|
|
1240
1265
|
currentNode.setAttribute(name, value);
|
|
1241
1266
|
}
|
|
1242
|
-
|
|
1267
|
+
if (_isClobbered(currentNode)) {
|
|
1268
|
+
_forceRemove(currentNode);
|
|
1269
|
+
} else {
|
|
1270
|
+
arrayPop(DOMPurify.removed);
|
|
1271
|
+
}
|
|
1243
1272
|
} catch (_) {}
|
|
1244
1273
|
}
|
|
1245
1274
|
|
|
@@ -1269,7 +1298,7 @@ function createDOMPurify() {
|
|
|
1269
1298
|
const parentNode = getParentNode(shadowNode);
|
|
1270
1299
|
|
|
1271
1300
|
/* Set the nesting depth of an element */
|
|
1272
|
-
if (shadowNode.nodeType ===
|
|
1301
|
+
if (shadowNode.nodeType === NODE_TYPE.element) {
|
|
1273
1302
|
if (parentNode && parentNode.__depth) {
|
|
1274
1303
|
/*
|
|
1275
1304
|
We want the depth of the node in the original tree, which can
|
|
@@ -1281,8 +1310,11 @@ function createDOMPurify() {
|
|
|
1281
1310
|
}
|
|
1282
1311
|
}
|
|
1283
1312
|
|
|
1284
|
-
/*
|
|
1285
|
-
|
|
1313
|
+
/*
|
|
1314
|
+
* Remove an element if nested too deeply to avoid mXSS
|
|
1315
|
+
* or if the __depth might have been tampered with
|
|
1316
|
+
*/
|
|
1317
|
+
if (shadowNode.__depth >= MAX_NESTING_DEPTH || shadowNode.__depth < 0 || numberIsNaN(shadowNode.__depth)) {
|
|
1286
1318
|
_forceRemove(shadowNode);
|
|
1287
1319
|
}
|
|
1288
1320
|
|
|
@@ -1364,7 +1396,7 @@ function createDOMPurify() {
|
|
|
1364
1396
|
elements being stripped by the parser */
|
|
1365
1397
|
body = _initDocument('<!---->');
|
|
1366
1398
|
importedNode = body.ownerDocument.importNode(dirty, true);
|
|
1367
|
-
if (importedNode.nodeType ===
|
|
1399
|
+
if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {
|
|
1368
1400
|
/* Node is already a body, use as is */
|
|
1369
1401
|
body = importedNode;
|
|
1370
1402
|
} else if (importedNode.nodeName === 'HTML') {
|
|
@@ -1407,7 +1439,7 @@ function createDOMPurify() {
|
|
|
1407
1439
|
const parentNode = getParentNode(currentNode);
|
|
1408
1440
|
|
|
1409
1441
|
/* Set the nesting depth of an element */
|
|
1410
|
-
if (currentNode.nodeType ===
|
|
1442
|
+
if (currentNode.nodeType === NODE_TYPE.element) {
|
|
1411
1443
|
if (parentNode && parentNode.__depth) {
|
|
1412
1444
|
/*
|
|
1413
1445
|
We want the depth of the node in the original tree, which can
|
|
@@ -1419,8 +1451,11 @@ function createDOMPurify() {
|
|
|
1419
1451
|
}
|
|
1420
1452
|
}
|
|
1421
1453
|
|
|
1422
|
-
/*
|
|
1423
|
-
|
|
1454
|
+
/*
|
|
1455
|
+
* Remove an element if nested too deeply to avoid mXSS
|
|
1456
|
+
* or if the __depth might have been tampered with
|
|
1457
|
+
*/
|
|
1458
|
+
if (currentNode.__depth >= MAX_NESTING_DEPTH || currentNode.__depth < 0 || numberIsNaN(currentNode.__depth)) {
|
|
1424
1459
|
_forceRemove(currentNode);
|
|
1425
1460
|
}
|
|
1426
1461
|
|