Skip to content

Commit

Permalink
feature: Added new config option to control comment sanitization
Browse files Browse the repository at this point in the history
docs: Added config flag description to README
docs: Added warning about happy-dom being unsafe with DOMPurify to README
  • Loading branch information
cure53 committed Apr 3, 2024
1 parent 1ebcfd4 commit 3a00950
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 10 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ After sanitizing your markup, you can also have a look at the property `DOMPurif

DOMPurify technically also works server-side with Node.js. Our support strives to follow the [Node.js release cycle](https://nodejs.org/en/about/releases/).

Running DOMPurify on the server requires a DOM to be present, which is probably no surprise. Usually, [jsdom](https://github.com/jsdom/jsdom) is the tool of choice and we **strongly recommend** to use the latest version of _jsdom_.
Running DOMPurify on the server requires a DOM to be present, which is probably no surprise. Usually, [jsdom](https://github.com/jsdom/jsdom) is the tool of choice and we **strongly recommend** to use the latest version of _jsdom_. Please be aware that tools like [happy-dom](https://github.com/capricorn86/happy-dom) exist but **are not considered safe** at this point. Combining DOMPurify with _happy-dom_ is currently not recommended and will likely lead to XSS.

Why? Because older versions of _jsdom_ are known to be buggy in ways that result in XSS _even if_ DOMPurify does everything 100% correctly. There are **known attack vectors** in, e.g. _jsdom v19.0.0_ that are fixed in _jsdom v20.0.0_ - and we really recommend to keep _jsdom_ up to date because of that.

Expand Down Expand Up @@ -167,6 +167,10 @@ Yes. The included default configuration values are pretty good already - but you
// allowing template parsing in user-controlled HTML is not advised at all.
// only use this mode if there is really no alternative.
const clean = DOMPurify.sanitize(dirty, {SAFE_FOR_TEMPLATES: true});


// change how e.g. comments containing risky HTML characters are treated.
const clean = DOMPurify.sanitize(dirty, {SAFE_FOR_XML: false});
```

### Control our allow-lists and block-lists
Expand Down
10 changes: 9 additions & 1 deletion dist/purify.cjs.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.cjs.js.map

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion dist/purify.es.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,11 @@ function createDOMPurify() {
*/
let SAFE_FOR_TEMPLATES = false;

/* Output should be safe even for XML used within HTML and alike.
* This means, DOMPurify removes comments when containing risky content.
*/
let SAFE_FOR_XML = true;

/* Decide if document with <html>... should be returned */
let WHOLE_DOCUMENT = false;

Expand Down Expand Up @@ -571,6 +576,7 @@ function createDOMPurify() {
ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true
SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
SAFE_FOR_XML = cfg.SAFE_FOR_XML || true; // Default true
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
RETURN_DOM = cfg.RETURN_DOM || false; // Default false
RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
Expand Down Expand Up @@ -991,7 +997,9 @@ function createDOMPurify() {
_forceRemove(currentNode);
return true;
}
if (currentNode.nodeType === 8 && regExpTest(/<[/\w]/g, currentNode.data)) {

/* Remove any kind of possibly harmful comments */
if (SAFE_FOR_XML && currentNode.nodeType === 8 && regExpTest(/<[/\w]/g, currentNode.data)) {
_forceRemove(currentNode);
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion dist/purify.es.mjs.map

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion 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.js.map

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion src/purify.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ function createDOMPurify(window = getGlobal()) {
*/
let SAFE_FOR_TEMPLATES = false;

/* Output should be safe even for XML used within HTML and alike.
* This means, DOMPurify removes comments when containing risky content.
*/
let SAFE_FOR_XML = true;

/* Decide if document with <html>... should be returned */
let WHOLE_DOCUMENT = false;

Expand Down Expand Up @@ -464,6 +469,7 @@ function createDOMPurify(window = getGlobal()) {
ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true
SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
SAFE_FOR_XML = cfg.SAFE_FOR_XML || true; // Default true
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
RETURN_DOM = cfg.RETURN_DOM || false; // Default false
RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
Expand Down Expand Up @@ -1016,7 +1022,12 @@ function createDOMPurify(window = getGlobal()) {
return true;
}

if (currentNode.nodeType === 8 && regExpTest(/<[/\w]/g, currentNode.data)) {
/* Remove any kind of possibly harmful comments */
if (
SAFE_FOR_XML &&
currentNode.nodeType === 8 &&
regExpTest(/<[/\w]/g, currentNode.data)
) {
_forceRemove(currentNode);
return true;
}
Expand Down

0 comments on commit 3a00950

Please sign in to comment.