sanitize-html
Advanced tools
Comparing version 1.0.3 to 1.1.0
44
index.js
@@ -36,4 +36,14 @@ var htmlparser = require('htmlparser2'); | ||
}); | ||
var transformTagsMap = {}; | ||
_.each(options.transformTags, function(transform, tag){ | ||
if (typeof transform === 'function') { | ||
transformTagsMap[tag] = transform; | ||
} else if (typeof transform === "string") { | ||
transformTagsMap[tag] = sanitizeHtml.simpleTransform(transform); | ||
} | ||
}); | ||
var depth = 0; | ||
var skipMap = {}; | ||
var transformMap = {}; | ||
var skipText = false; | ||
@@ -43,2 +53,12 @@ var parser = new htmlparser.Parser({ | ||
var skip = false; | ||
if (_.has(transformTagsMap, name)) { | ||
var transformedTag = transformTagsMap[name](name, attribs); | ||
attribs = transformedTag.attribs; | ||
if (name !== transformedTag.tagName) { | ||
name = transformedTag.tagName; | ||
transformMap[depth] = transformedTag.tagName; | ||
} | ||
} | ||
if (!_.has(allowedTagsMap, name)) { | ||
@@ -99,2 +119,6 @@ skip = true; | ||
} | ||
if (transformMap[depth]) { | ||
name = transformMap[depth]; | ||
delete transformMap[depth]; | ||
} | ||
result += "</" + name + ">"; | ||
@@ -149,1 +173,21 @@ } | ||
}; | ||
sanitizeHtml.simpleTransform = function(newTagName, newAttribs, merge) { | ||
merge = (merge == undefined) ? true : merge; | ||
newAttribs = newAttribs || {}; | ||
return function(tagName, attribs) { | ||
if (merge) { | ||
for (attrib in newAttribs) { | ||
attribs[attrib] = newAttribs[attrib]; | ||
} | ||
} else { | ||
attribs = newAttribs; | ||
} | ||
return { | ||
tagName: newTagName, | ||
attribs: attribs | ||
} | ||
}; | ||
}; |
{ | ||
"name": "sanitize-html", | ||
"version": "1.0.3", | ||
"version": "1.1.0", | ||
"description": "Clean up user-submitted HTML, preserving whitelisted elements and whitelisted attributes on a per-element basis", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -70,8 +70,53 @@ # sanitize-html | ||
### Transformations | ||
What if you want to add or change an attribute? What if you want to transform one tag to another? No problem, it's simple! | ||
The easiest way (will change all `ol` tags to `ul` tags): | ||
clean = sanitizeHtml(dirty, { | ||
transformTags: { | ||
'ol': 'ul', | ||
} | ||
}); | ||
The most advanced usage: | ||
clean = sanitizeHtml(dirty, { | ||
transformTags: { | ||
'ol': function(tagName, attribs) { | ||
// My own custom magic goes here | ||
return { | ||
tagName: 'ul', | ||
attribs: { | ||
class: 'foo' | ||
} | ||
}; | ||
} | ||
} | ||
}); | ||
There is also a helper method which should be enough for simple cases in which you want to change the tag and/or add some attributes: | ||
clean = sanitizeHtml(dirty, { | ||
transformTags: { | ||
'ol': sanitizeHtml.simpleTransform('ul', {class: 'foo'}), | ||
} | ||
}); | ||
The `simpleTransform` helper method has 3 parameters: | ||
simpleTransform(newTag, newAttributes, shouldMerge) | ||
The last parameter (`shouldMerge`) is set to `true` by default. When `true`, `simpleTransform` will merge the current attributes with the new ones (`newAttributes`). When `false`, all existing attributes are discarded. | ||
## Changelog | ||
1.0.3: fixed several more javascript URL attack vectors after [studying the XSS filter evasion cheat sheet](https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet) to better understand my enemy. Whitespace characters (codes from 0 to 32), which browsers ignore in URLs in certain cases allowing the "javascript" scheme to be snuck in, are now stripped out when checking for naughty URLs. Thanks again to pinpickle. | ||
1.1.0: the `transformTags` option was added. Thanks to [kl3ryk](https://github.com/kl3ryk). | ||
1.0.2: fixed a javascript URL attack vector. naughtyHref must entity-decode URLs and also check for mixed-case scheme names. Thanks to pinpickle. | ||
1.0.3: fixed several more javascript URL attack vectors after [studying the XSS filter evasion cheat sheet](https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet) to better understand my enemy. Whitespace characters (codes from 0 to 32), which browsers ignore in URLs in certain cases allowing the "javascript" scheme to be snuck in, are now stripped out when checking for naughty URLs. Thanks again to [pinpickle](https://github.com/pinpickle). | ||
1.0.2: fixed a javascript URL attack vector. naughtyHref must entity-decode URLs and also check for mixed-case scheme names. Thanks to [pinpickle](https://github.com/pinpickle). | ||
1.0.1: Doc tweaks. | ||
@@ -78,0 +123,0 @@ |
@@ -64,3 +64,25 @@ var assert = require("assert"); | ||
}); | ||
it('should replace ol to ul', function() { | ||
assert.equal(sanitizeHtml('<ol><li>Hello world</li></ol>', { transformTags: {ol: 'ul'} }), '<ul><li>Hello world</li></ul>'); | ||
}); | ||
it('should replace ol to ul and add class attribute with foo value', function() { | ||
assert.equal(sanitizeHtml('<ol><li>Hello world</li></ol>', { transformTags: {ol: sanitizeHtml.simpleTransform('ul', {class: 'foo'})}, allowedAttributes: { ul: ['class'] } }), '<ul class="foo"><li>Hello world</li></ul>'); | ||
}); | ||
it('should replace ol to ul, left attributes foo and bar untouched, remove baz attribute and add class attributte with foo value', function() { | ||
assert.equal(sanitizeHtml('<ol foo="foo" bar="bar" baz="baz"><li>Hello world</li></ol>', { transformTags: {ol: sanitizeHtml.simpleTransform('ul', {class: 'foo'})}, allowedAttributes: { ul: ['foo', 'bar', 'class'] } }), '<ul foo="foo" bar="bar" class="foo"><li>Hello world</li></ul>'); | ||
}); | ||
it('should replace ol to ul and replace all attributes to class attribute with foo value', function() { | ||
assert.equal(sanitizeHtml('<ol foo="foo" bar="bar" baz="baz"><li>Hello world</li></ol>', { transformTags: {ol: sanitizeHtml.simpleTransform('ul', {class: 'foo'}, false)}, allowedAttributes: { ul: ['foo', 'bar', 'class'] } }), '<ul class="foo"><li>Hello world</li></ul>'); | ||
}); | ||
it('should replace ol to ul and add attribute class with foo value and attribute bar with bar value', function() { | ||
assert.equal(sanitizeHtml('<ol><li>Hello world</li></ol>', { transformTags: {ol: function(tagName, attribs){ | ||
attribs.class = 'foo'; | ||
attribs.bar = 'bar'; | ||
return { | ||
tagName: 'ul', | ||
attribs: attribs | ||
} | ||
}}, allowedAttributes: { ul: ['bar', 'class'] } }), '<ul class="foo" bar="bar"><li>Hello world</li></ul>'); | ||
}); | ||
}); | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
24240
266
145