Skip to content

Commit

Permalink
Revert "Escape disallowed tags"
Browse files Browse the repository at this point in the history
  • Loading branch information
boutell authored Sep 20, 2019
1 parent d48f3dd commit a338283
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 62 deletions.
10 changes: 0 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -488,16 +488,6 @@ Note that if you use this option you are responsible for stating the entire list

The content still gets escaped properly, with the exception of the `script` and `style` tags. *Allowing either `script` or `style` leaves you open to XSS attacks. Don't do that* unless you have good reason to trust their origin.
### Escaping the content of a disallowed tag
Instead of discarding, or keeping text only, you may enable escaping of the entire content:
```javascript
escapeDisallowedTags: true
```
This will transform `<disallowed>content</disallowed>` to `&lt;disallowed&gt;content&lt;/disallowed&gt;`
## About P'unk Avenue and Apostrophe

`sanitize-html` was created at [P'unk Avenue](http://punkave.com) for use in ApostropheCMS, an open-source content management system built on node.js. If you like `sanitize-html` you should definitely [check out apostrophecms.org](http://apostrophecms.org).
Expand Down
37 changes: 6 additions & 31 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ const VALID_HTML_ATTRIBUTE_NAME = /^[^\0\t\n\f\r /<=>]+$/;

function sanitizeHtml(html, options, _recursing) {
var result = '';
var tempResult = '';

function Frame(tag, attribs) {
var that = this;
Expand Down Expand Up @@ -138,7 +137,6 @@ function sanitizeHtml(html, options, _recursing) {
var skipMap = {};
var transformMap = {};
var skipText = false;
var escapeDepth = 0;
var skipTextDepth = 0;

var parser = new htmlparser.Parser({
Expand All @@ -147,9 +145,6 @@ function sanitizeHtml(html, options, _recursing) {
skipTextDepth++;
return;
}
if (escapeDepth > 0) {
escapeDepth++;
}
var frame = new Frame(name, attribs);
stack.push(frame);

Expand Down Expand Up @@ -182,26 +177,16 @@ function sanitizeHtml(html, options, _recursing) {

if (options.allowedTags && options.allowedTags.indexOf(name) === -1) {
skip = true;
if (!options.escapeDisallowedTags) {
// We don't want to skip disallowedTags tags, just escape them
if (nonTextTagsArray.indexOf(name) !== -1) {
skipText = true;
skipTextDepth = 1;
}
skipMap[depth] = true;
if (nonTextTagsArray.indexOf(name) !== -1) {
skipText = true;
skipTextDepth = 1;
}
skipMap[depth] = true;
}
depth++;
if (skip) {
if (!options.escapeDisallowedTags) {
// We want the contents but not this tag
return;
}
if (escapeDepth === 0) {
tempResult = result;
result = '';
escapeDepth++;
}
// We want the contents but not this tag
return;
}
result += '<' + name;
if (!allowedAttributesMap || has(allowedAttributesMap, name) || allowedAttributesMap['*']) {
Expand Down Expand Up @@ -339,10 +324,6 @@ function sanitizeHtml(html, options, _recursing) {
}
if (options.selfClosing.indexOf(name) !== -1) {
result += " />";
if (escapeDepth > 0 && --escapeDepth === 0) {
result = tempResult + escapeHtml(result);
tempResult = '';
}
} else {
result += ">";
if (frame.innerText && !hasText && !options.textFilter) {
Expand Down Expand Up @@ -392,7 +373,6 @@ function sanitizeHtml(html, options, _recursing) {
return;
}
}
var shouldEscape = escapeDepth > 0 && --escapeDepth === 0;

var frame = stack.pop();
if (!frame) {
Expand Down Expand Up @@ -425,10 +405,6 @@ function sanitizeHtml(html, options, _recursing) {
}

result += "</" + name + ">";
if (shouldEscape) {
result = tempResult + escapeHtml(result);
tempResult = '';
}
}
}, options.parser);
parser.write(html);
Expand Down Expand Up @@ -596,7 +572,6 @@ sanitizeHtml.defaults = {
allowedTags: [ 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol',
'nl', 'li', 'b', 'i', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div',
'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre', 'iframe' ],
escapeDisallowedTags: false,
allowedAttributes: {
a: [ 'href', 'name', 'target' ],
// We don't currently allow img itself by default, but this
Expand Down
21 changes: 0 additions & 21 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ describe('sanitizeHtml', function() {
it('should reject markup not whitelisted without destroying its text', function() {
assert.equal(sanitizeHtml('<div><wiggly>Hello</wiggly></div>'), '<div>Hello</div>');
});
it('should escape markup not whitelisted', function() {
assert.equal(sanitizeHtml('<div><wiggly>Hello</wiggly></div>', { escapeDisallowedTags: true }), '<div>&lt;wiggly&gt;Hello&lt;/wiggly&gt;</div>');
});
it('should accept a custom list of allowed tags', function() {
assert.equal(sanitizeHtml('<blue><red><green>Cheese</green></red></blue>', { allowedTags: [ 'blue', 'green' ] }), '<blue><green>Cheese</green></blue>');
});
Expand Down Expand Up @@ -822,22 +819,4 @@ describe('sanitizeHtml', function() {
// }
// }), '<img src="&lt;0&amp;0;0.2&amp;" />');
// });
it('should escape markup not whitelisted and all its children', function() {
assert.equal(
sanitizeHtml('<div><wiggly>Hello<p>World</p></wiggly></div>', { escapeDisallowedTags: true }),
'<div>&lt;wiggly&gt;Hello&lt;p&gt;World&lt;/p&gt;&lt;/wiggly&gt;</div>'
);
});
it('should escape markup even when deocdeEntities is false', function() {
assert.equal(
sanitizeHtml('<wiggly>Hello</wiggly>', { escapeDisallowedTags: true, parser: { decodeEntities: false } }),
'&lt;wiggly&gt;Hello&lt;/wiggly&gt;'
);
});
it('should escape markup not whitelisted even with not whitelisted children', function() {
assert.equal(
sanitizeHtml('<div><wiggly>Hello<p>World</p><tiggly>JS</tiggly></wiggly></div>', { escapeDisallowedTags: true }),
'<div>&lt;wiggly&gt;Hello&lt;p&gt;World&lt;/p&gt;&lt;tiggly&gt;JS&lt;/tiggly&gt;&lt;/wiggly&gt;</div>'
);
});
});

0 comments on commit a338283

Please sign in to comment.