Skip to content

Commit c183cd6

Browse files
committed
fix: Fixed a config-dependent bypass caused by skipped attribute checks, thanks @parrot409
1 parent 6e76ece commit c183cd6

File tree

6 files changed

+46
-19
lines changed

6 files changed

+46
-19
lines changed

dist/purify.cjs.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/purify.es.mjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,6 +1147,8 @@ function createDOMPurify() {
11471147
while (shadowNode = shadowIterator.nextNode()) {
11481148
/* Execute a hook if present */
11491149
_executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
1150+
/* Check attributes first */
1151+
_sanitizeAttributes(shadowNode);
11501152
/* Sanitize tags and elements */
11511153
if (_sanitizeElements(shadowNode)) {
11521154
continue;
@@ -1155,8 +1157,6 @@ function createDOMPurify() {
11551157
if (shadowNode.content instanceof DocumentFragment) {
11561158
_sanitizeShadowDOM(shadowNode.content);
11571159
}
1158-
/* Check attributes, sanitize if necessary */
1159-
_sanitizeAttributes(shadowNode);
11601160
}
11611161
/* Execute a hook if present */
11621162
_executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
@@ -1244,6 +1244,8 @@ function createDOMPurify() {
12441244
const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
12451245
/* Now start iterating over the created document */
12461246
while (currentNode = nodeIterator.nextNode()) {
1247+
/* Check attributes first */
1248+
_sanitizeAttributes(currentNode);
12471249
/* Sanitize tags and elements */
12481250
if (_sanitizeElements(currentNode)) {
12491251
continue;
@@ -1252,8 +1254,6 @@ function createDOMPurify() {
12521254
if (currentNode.content instanceof DocumentFragment) {
12531255
_sanitizeShadowDOM(currentNode.content);
12541256
}
1255-
/* Check attributes, sanitize if necessary */
1256-
_sanitizeAttributes(currentNode);
12571257
}
12581258
/* If we sanitized `dirty` in-place, return it. */
12591259
if (IN_PLACE) {

dist/purify.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/purify.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/purify.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,9 @@ function createDOMPurify(window: WindowLike = getGlobal()): DOMPurify {
14151415
/* Execute a hook if present */
14161416
_executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
14171417

1418+
/* Check attributes first */
1419+
_sanitizeAttributes(shadowNode);
1420+
14181421
/* Sanitize tags and elements */
14191422
if (_sanitizeElements(shadowNode)) {
14201423
continue;
@@ -1424,9 +1427,6 @@ function createDOMPurify(window: WindowLike = getGlobal()): DOMPurify {
14241427
if (shadowNode.content instanceof DocumentFragment) {
14251428
_sanitizeShadowDOM(shadowNode.content);
14261429
}
1427-
1428-
/* Check attributes, sanitize if necessary */
1429-
_sanitizeAttributes(shadowNode);
14301430
}
14311431

14321432
/* Execute a hook if present */
@@ -1537,6 +1537,9 @@ function createDOMPurify(window: WindowLike = getGlobal()): DOMPurify {
15371537

15381538
/* Now start iterating over the created document */
15391539
while ((currentNode = nodeIterator.nextNode())) {
1540+
/* Check attributes first */
1541+
_sanitizeAttributes(currentNode);
1542+
15401543
/* Sanitize tags and elements */
15411544
if (_sanitizeElements(currentNode)) {
15421545
continue;
@@ -1546,9 +1549,6 @@ function createDOMPurify(window: WindowLike = getGlobal()): DOMPurify {
15461549
if (currentNode.content instanceof DocumentFragment) {
15471550
_sanitizeShadowDOM(currentNode.content);
15481551
}
1549-
1550-
/* Check attributes, sanitize if necessary */
1551-
_sanitizeAttributes(currentNode);
15521552
}
15531553

15541554
/* If we sanitized `dirty` in-place, return it. */

test/test-suite.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2104,5 +2104,32 @@
21042104
let clean = DOMPurify.sanitize(dirty, config);
21052105
assert.contains(clean, expected);
21062106
});
2107+
2108+
QUnit.test('Test proper handling of attributes with RETURN_DOM', function (assert) {
2109+
const dirty = '<body onload="alert(1)">&lt;a<!-- <f --></body>';
2110+
const config = {
2111+
RETURN_DOM: true
2112+
};
2113+
const expected = '<body>&lt;a</body>';
2114+
let clean = DOMPurify.sanitize(dirty, config);
2115+
2116+
let iframe = document.createElement('iframe')
2117+
iframe.srcdoc = `<html><head></head>${clean.outerHTML}</html>`
2118+
document.body.appendChild(iframe); // alert test
2119+
assert.contains(clean.outerHTML, expected);
2120+
});
2121+
2122+
QUnit.test('Test proper handling of data-attribiutes in XML modes', function (assert) {
2123+
const dirty = '<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg"><a xmlns:data-slonser="http://www.w3.org/1999/xlink" data-slonser:href="javascript:alert(1)"><text x="20" y="35">Click me!</text></a></svg>';
2124+
const config = {
2125+
PARSER_MEDIA_TYPE: 'application/xhtml+xml'
2126+
};
2127+
const expected = [
2128+
'<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"600\" width=\"800\"><a><text y=\"35\" x=\"20\">Click me!</text></a></svg>',
2129+
'<svg height=\"600\" width=\"800\" xmlns=\"http://www.w3.org/2000/svg\"><a><text y=\"35\" x=\"20\">Click me!</text></a></svg>'
2130+
];
2131+
let clean = DOMPurify.sanitize(dirty, config);
2132+
assert.contains(clean, expected);
2133+
});
21072134
};
21082135
});

0 commit comments

Comments
 (0)