Skip to content

Commit

Permalink
fix: Fixed a config-dependent bypass caused by skipped attribute chec…
Browse files Browse the repository at this point in the history
…ks, thanks @parrot409
  • Loading branch information
cure53 committed Dec 6, 2024
1 parent 6e76ece commit c183cd6
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 19 deletions.
8 changes: 4 additions & 4 deletions dist/purify.cjs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions dist/purify.es.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,8 @@ function createDOMPurify() {
while (shadowNode = shadowIterator.nextNode()) {
/* Execute a hook if present */
_executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
/* Check attributes first */
_sanitizeAttributes(shadowNode);
/* Sanitize tags and elements */
if (_sanitizeElements(shadowNode)) {
continue;
Expand All @@ -1155,8 +1157,6 @@ function createDOMPurify() {
if (shadowNode.content instanceof DocumentFragment) {
_sanitizeShadowDOM(shadowNode.content);
}
/* Check attributes, sanitize if necessary */
_sanitizeAttributes(shadowNode);
}
/* Execute a hook if present */
_executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
Expand Down Expand Up @@ -1244,6 +1244,8 @@ function createDOMPurify() {
const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
/* Now start iterating over the created document */
while (currentNode = nodeIterator.nextNode()) {
/* Check attributes first */
_sanitizeAttributes(currentNode);
/* Sanitize tags and elements */
if (_sanitizeElements(currentNode)) {
continue;
Expand All @@ -1252,8 +1254,6 @@ function createDOMPurify() {
if (currentNode.content instanceof DocumentFragment) {
_sanitizeShadowDOM(currentNode.content);
}
/* Check attributes, sanitize if necessary */
_sanitizeAttributes(currentNode);
}
/* If we sanitized `dirty` in-place, return it. */
if (IN_PLACE) {
Expand Down
8 changes: 4 additions & 4 deletions dist/purify.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/purify.min.js

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/purify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1415,6 +1415,9 @@ function createDOMPurify(window: WindowLike = getGlobal()): DOMPurify {
/* Execute a hook if present */
_executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);

/* Check attributes first */
_sanitizeAttributes(shadowNode);

/* Sanitize tags and elements */
if (_sanitizeElements(shadowNode)) {
continue;
Expand All @@ -1424,9 +1427,6 @@ function createDOMPurify(window: WindowLike = getGlobal()): DOMPurify {
if (shadowNode.content instanceof DocumentFragment) {
_sanitizeShadowDOM(shadowNode.content);
}

/* Check attributes, sanitize if necessary */
_sanitizeAttributes(shadowNode);
}

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

/* Now start iterating over the created document */
while ((currentNode = nodeIterator.nextNode())) {
/* Check attributes first */
_sanitizeAttributes(currentNode);

/* Sanitize tags and elements */
if (_sanitizeElements(currentNode)) {
continue;
Expand All @@ -1546,9 +1549,6 @@ function createDOMPurify(window: WindowLike = getGlobal()): DOMPurify {
if (currentNode.content instanceof DocumentFragment) {
_sanitizeShadowDOM(currentNode.content);
}

/* Check attributes, sanitize if necessary */
_sanitizeAttributes(currentNode);
}

/* If we sanitized `dirty` in-place, return it. */
Expand Down
27 changes: 27 additions & 0 deletions test/test-suite.js
Original file line number Diff line number Diff line change
Expand Up @@ -2104,5 +2104,32 @@
let clean = DOMPurify.sanitize(dirty, config);
assert.contains(clean, expected);
});

QUnit.test('Test proper handling of attributes with RETURN_DOM', function (assert) {
const dirty = '<body onload="alert(1)">&lt;a<!-- <f --></body>';
const config = {
RETURN_DOM: true
};
const expected = '<body>&lt;a</body>';
let clean = DOMPurify.sanitize(dirty, config);

let iframe = document.createElement('iframe')
iframe.srcdoc = `<html><head></head>${clean.outerHTML}</html>`
document.body.appendChild(iframe); // alert test
assert.contains(clean.outerHTML, expected);
});

QUnit.test('Test proper handling of data-attribiutes in XML modes', function (assert) {
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>';
const config = {
PARSER_MEDIA_TYPE: 'application/xhtml+xml'
};
const expected = [
'<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"600\" width=\"800\"><a><text y=\"35\" x=\"20\">Click me!</text></a></svg>',
'<svg height=\"600\" width=\"800\" xmlns=\"http://www.w3.org/2000/svg\"><a><text y=\"35\" x=\"20\">Click me!</text></a></svg>'
];
let clean = DOMPurify.sanitize(dirty, config);
assert.contains(clean, expected);
});
};
});

0 comments on commit c183cd6

Please sign in to comment.