dompurify 3.2.5 → 3.2.6
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 +6 -6
- package/dist/purify.cjs.d.ts +1 -1
- package/dist/purify.cjs.js +26 -21
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.d.mts +1 -1
- package/dist/purify.es.mjs +26 -21
- package/dist/purify.es.mjs.map +1 -1
- package/dist/purify.js +26 -21
- 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
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG.
|
|
6
6
|
|
|
7
|
-
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.2.
|
|
7
|
+
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.2.6**.
|
|
8
8
|
|
|
9
9
|
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.
|
|
10
10
|
|
|
11
11
|
**Note that [DOMPurify v2.5.8](https://github.com/cure53/DOMPurify/releases/tag/2.5.8) 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).**
|
|
12
12
|
|
|
13
|
-
Our automated tests cover [28 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 v18.x, v19.x, v20.x, v21.x,
|
|
13
|
+
Our automated tests cover [28 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 v18.x, v19.x, v20.x, v21.x, v22.x and v23.x, running DOMPurify on [jsdom](https://github.com/jsdom/jsdom). Older Node versions are known to work as well, but hey... no guarantees.
|
|
14
14
|
|
|
15
15
|
DOMPurify is written by security people who have vast background in web attacks and XSS. Fear not. For more details please also read about our [Security Goals & Threat Model](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model). Please, read it. Like, really.
|
|
16
16
|
|
|
@@ -22,10 +22,10 @@ DOMPurify sanitizes HTML and prevents XSS attacks. You can feed DOMPurify with s
|
|
|
22
22
|
|
|
23
23
|
It's easy. Just include DOMPurify on your website.
|
|
24
24
|
|
|
25
|
-
### Using the unminified
|
|
25
|
+
### Using the unminified version (source-map available)
|
|
26
26
|
|
|
27
27
|
```html
|
|
28
|
-
<script type="text/javascript" src="
|
|
28
|
+
<script type="text/javascript" src="dist/purify.js"></script>
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
### Using the minified and tested production version (source-map available)
|
|
@@ -303,7 +303,7 @@ const clean = DOMPurify.sanitize(dirty, {
|
|
|
303
303
|
TRUSTED_TYPES_POLICY: trustedTypes.createPolicy({
|
|
304
304
|
createHTML(s) { return s},
|
|
305
305
|
createScriptURL(s) { return s},
|
|
306
|
-
}
|
|
306
|
+
})
|
|
307
307
|
});
|
|
308
308
|
```
|
|
309
309
|
### Influence how we sanitize
|
|
@@ -385,7 +385,7 @@ DOMPurify.addHook(
|
|
|
385
385
|
|
|
386
386
|
We are currently using Github Actions in combination with BrowserStack. This gives us the possibility to confirm for each and every commit that all is going according to plan in all supported browsers. Check out the build logs here: https://github.com/cure53/DOMPurify/actions
|
|
387
387
|
|
|
388
|
-
You can further run local tests by executing `npm test`.
|
|
388
|
+
You can further run local tests by executing `npm run test`.
|
|
389
389
|
|
|
390
390
|
All relevant commits will be signed with the key `0x24BB6BF4` for additional security (since 8th of April 2016).
|
|
391
391
|
|
package/dist/purify.cjs.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @license DOMPurify 3.2.
|
|
1
|
+
/*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE */
|
|
2
2
|
|
|
3
3
|
import { TrustedTypePolicy, TrustedHTML, TrustedTypesWindow } from 'trusted-types/lib';
|
|
4
4
|
|
package/dist/purify.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @license DOMPurify 3.2.
|
|
1
|
+
/*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE */
|
|
2
2
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
@@ -204,7 +204,7 @@ const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
|
|
|
204
204
|
const TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); // eslint-disable-line unicorn/better-regex
|
|
205
205
|
const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
|
|
206
206
|
const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
|
|
207
|
-
const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
|
|
207
|
+
const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
|
|
208
208
|
);
|
|
209
209
|
const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
|
|
210
210
|
const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
|
|
@@ -301,7 +301,7 @@ const _createHooksMap = function _createHooksMap() {
|
|
|
301
301
|
function createDOMPurify() {
|
|
302
302
|
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
303
303
|
const DOMPurify = root => createDOMPurify(root);
|
|
304
|
-
DOMPurify.version = '3.2.
|
|
304
|
+
DOMPurify.version = '3.2.6';
|
|
305
305
|
DOMPurify.removed = [];
|
|
306
306
|
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
|
307
307
|
// Not running in a browser, provide a factory function
|
|
@@ -540,8 +540,8 @@ function createDOMPurify() {
|
|
|
540
540
|
URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
|
|
541
541
|
DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
|
|
542
542
|
FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
|
|
543
|
-
FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
|
|
544
|
-
FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
|
|
543
|
+
FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});
|
|
544
|
+
FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});
|
|
545
545
|
USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;
|
|
546
546
|
ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
|
|
547
547
|
ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
|
|
@@ -906,7 +906,7 @@ function createDOMPurify() {
|
|
|
906
906
|
allowedTags: ALLOWED_TAGS
|
|
907
907
|
});
|
|
908
908
|
/* Detect mXSS attempts abusing namespace confusion */
|
|
909
|
-
if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
|
|
909
|
+
if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
|
|
910
910
|
_forceRemove(currentNode);
|
|
911
911
|
return true;
|
|
912
912
|
}
|
|
@@ -1058,7 +1058,8 @@ function createDOMPurify() {
|
|
|
1058
1058
|
value: attrValue
|
|
1059
1059
|
} = attr;
|
|
1060
1060
|
const lcName = transformCaseFunc(name);
|
|
1061
|
-
|
|
1061
|
+
const initValue = attrValue;
|
|
1062
|
+
let value = name === 'value' ? initValue : stringTrim(initValue);
|
|
1062
1063
|
/* Execute a hook if present */
|
|
1063
1064
|
hookEvent.attrName = lcName;
|
|
1064
1065
|
hookEvent.attrValue = value;
|
|
@@ -1084,10 +1085,9 @@ function createDOMPurify() {
|
|
|
1084
1085
|
if (hookEvent.forceKeepAttr) {
|
|
1085
1086
|
continue;
|
|
1086
1087
|
}
|
|
1087
|
-
/* Remove attribute */
|
|
1088
|
-
_removeAttribute(name, currentNode);
|
|
1089
1088
|
/* Did the hooks approve of the attribute? */
|
|
1090
1089
|
if (!hookEvent.keepAttr) {
|
|
1090
|
+
_removeAttribute(name, currentNode);
|
|
1091
1091
|
continue;
|
|
1092
1092
|
}
|
|
1093
1093
|
/* Work around a security issue in jQuery 3.0 */
|
|
@@ -1104,6 +1104,7 @@ function createDOMPurify() {
|
|
|
1104
1104
|
/* Is `value` valid for this attribute? */
|
|
1105
1105
|
const lcTag = transformCaseFunc(currentNode.nodeName);
|
|
1106
1106
|
if (!_isValidAttribute(lcTag, lcName, value)) {
|
|
1107
|
+
_removeAttribute(name, currentNode);
|
|
1107
1108
|
continue;
|
|
1108
1109
|
}
|
|
1109
1110
|
/* Handle attributes that require Trusted Types */
|
|
@@ -1124,19 +1125,23 @@ function createDOMPurify() {
|
|
|
1124
1125
|
}
|
|
1125
1126
|
}
|
|
1126
1127
|
/* Handle invalid data-* attribute set by try-catching it */
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1128
|
+
if (value !== initValue) {
|
|
1129
|
+
try {
|
|
1130
|
+
if (namespaceURI) {
|
|
1131
|
+
currentNode.setAttributeNS(namespaceURI, name, value);
|
|
1132
|
+
} else {
|
|
1133
|
+
/* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
|
|
1134
|
+
currentNode.setAttribute(name, value);
|
|
1135
|
+
}
|
|
1136
|
+
if (_isClobbered(currentNode)) {
|
|
1137
|
+
_forceRemove(currentNode);
|
|
1138
|
+
} else {
|
|
1139
|
+
arrayPop(DOMPurify.removed);
|
|
1140
|
+
}
|
|
1141
|
+
} catch (_) {
|
|
1142
|
+
_removeAttribute(name, currentNode);
|
|
1138
1143
|
}
|
|
1139
|
-
}
|
|
1144
|
+
}
|
|
1140
1145
|
}
|
|
1141
1146
|
/* Execute a hook if present */
|
|
1142
1147
|
_executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
|