Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

resanitize

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

resanitize - npm Package Compare versions

Comparing version 0.1.11 to 0.2.0

test/fixtures/comments.json

57

package.json

@@ -1,18 +0,41 @@

{ "name" : "resanitize"
, "author" : "Dan MacTough <danmactough@gmail.com>"
, "description" : "Regular expression-based HTML sanitizer and ad remover, geared toward RSS feed descriptions"
, "version" : "0.1.11"
, "keywords" : ["sanitize", "html", "regexp", "security"]
, "homepage" : "http://github.com/danmactough/node-resanitize"
, "repository" :
{ "type" : "git"
, "url" : "git://github.com/danmactough/node-resanitize.git"
}
, "bugs" :
{ "url" : "http://github.com/danmactough/node-resanitize/issues"}
, "main" : "./resanitize.js"
, "engines" :
{ "node" : ">= 0.6.0" }
, "dependencies" : {}
, "devDependencies": {}
{
"name": "resanitize",
"author": "Dan MacTough <danmactough@gmail.com>",
"description": "Regular expression-based HTML sanitizer and ad remover, geared toward RSS feed descriptions",
"version": "0.2.0",
"keywords": [
"sanitize",
"html",
"regexp",
"security"
],
"homepage": "http://github.com/danmactough/node-resanitize",
"repository": {
"type": "git",
"url": "git://github.com/danmactough/node-resanitize.git"
},
"bugs": {
"url": "http://github.com/danmactough/node-resanitize/issues"
},
"main": "./resanitize.js",
"engines": {
"node": ">= 0.6.0"
},
"dependencies": {},
"devDependencies": {
"mocha": "~1.13.0"
},
"licenses": [
{
"type": "MIT",
"url": "https://raw.github.com/danmactough/node-resanitize/master/LICENSE"
}
],
"directories": {
"test": "test"
},
"scripts": {
"test": "mocha"
},
"license": "MIT"
}

@@ -19,2 +19,15 @@ # Resanitize - Regular expression-based HTML sanitizer and ad remover, geared toward RSS feed descriptions

resanitize(html); // => '<div>Headline</div>'
```
```
## Notes
This module's opinion of "sanitized" might not meet your security requirements.
The mere fact that it uses regular expressions should make this disclaimer
unnecessary, but just to be clear: if you intend to display arbitrary user input
that includes HTML, you're going to want something more robust.
Note that the `stripUnsafeTags` method will loop over the strip an arbitrary
number of times (10) to try to strip maliciously nested html tags. After the
maximum number of iterations is reached, if the string still appears to contain
any unsafe tags, it is deemed unsafe and set to an empty string. If this seems
unexpected and/or is causing any problems, please raise an [issue](//github.com/danmactough/node-resanitize/issues).

@@ -87,3 +87,3 @@ /*!

function stripComments (str) {
return str.replace(/<!--[^>]*?>.*?<![^>]*?-->/g, '');
return str.replace(/<!--[^>]*?-->/g, '');
}

@@ -96,3 +96,4 @@ module.exports.stripComments = stripComments;

function filterAttrs () {
var allowed = [];
var allowed = []
, script = /javascript:/i;
if (Array.isArray(arguments[0])) {

@@ -104,3 +105,3 @@ allowed = arguments[0];

return function (attr, name) {
if ( ~allowed.indexOf(name && name.toLowerCase()) ) {
if ( ~allowed.indexOf(name && name.toLowerCase()) && !script.test(attr) ) {
return attr;

@@ -118,10 +119,26 @@ } else {

function stripAttrs () {
var banned = [];
var banned = []
, regexes = []
, script = /javascript:/i;
if (Array.isArray(arguments[0])) {
banned = arguments[0];
banned = arguments[0].filter(function (attr) {
if ('string' === typeof attr) {
return true;
}
else if (attr.constructor && 'RegExp' === attr.constructor.name) {
regexes.push(attr);
}
});
} else {
banned = Array.prototype.slice.call(arguments);
banned = Array.prototype.slice.call(arguments).filter(function (attr) {
if ('string' === typeof attr) {
return true;
}
else if (attr.constructor && 'RegExp' === attr.constructor.name) {
regexes.push(attr);
}
});
}
return function (attr, name) {
if ( ~banned.indexOf(name && name.toLowerCase()) ) {
if ( ~banned.indexOf(name && name.toLowerCase()) || script.test(attr) || regexes.some(function (re) { return re.test(name); }) ) {
return '';

@@ -141,3 +158,3 @@ } else {

if ('function' === typeof nextFilter) {
rematch = rematch.replace(/(\S+)=("|')[^>]+?\2/g, nextFilter);
rematch = rematch.replace(/([^\s"']+?)=("|')[^>]+?\2/g, nextFilter);
}

@@ -160,26 +177,16 @@ // Cleanup extra whitespace

, 'style'
, 'accesskey'
, 'action'
, 'autocomplete'
, 'autofocus'
, 'clear'
, 'contextmenu'
, 'contenteditable'
, 'draggable'
, 'dropzone'
, 'method'
, 'tabindex'
, 'target'
, 'onclick'
, 'ondblclick'
, 'onmousedown'
, 'onmousemove'
, 'onmouseover'
, 'onmouseout'
, 'onmouseup'
, 'onkeydown'
, 'onkeypress'
, 'onkeyup'
, 'onabort'
, 'onerror'
, 'onload'
, 'onresize'
, 'onscroll'
, 'onunload'
, 'onblur'
, 'onchange'
, 'onfocus'
, 'onreset'
, 'onselect'
, 'onsubmit'
, /on\w+/i
, /data-\w+/i
];

@@ -191,15 +198,26 @@ return str.replace(/<([^ >]+?) [^>]*?>/g, filterTag(stripAttrs(unsafe)));

function stripUnsafeTags (str) {
return str.replace(/<form[^>]*?>[\s\S]*?<\/form>/gi, '')
.replace(/<input[^>]*?>[\s\S]*?<\/input>/gi, '')
.replace(/<\/?(?:form|input|font|blink)[^>]*?>/gi, '')
// These are XSS/security risks
.replace(/<script[^>]*?>[\s\S]*?<\/script>/gi, '')
.replace(/<style[^>]*?>[\s\S]*?<\/style>/gi, '') // shouldn't work anyway...
.replace(/<comment[^>]*?>[\s\S]*?<\/comment>/gi, '')
.replace(/<plaintext[^>]*?>[\s\S]*?<\/plaintext>/gi, '')
.replace(/<xmp[^>]*?>[\s\S]*?<\/xmp>/gi, '')
.replace(/<\/?(?:link|listing|meta|body|frame|frameset)[^>]*?>/gi, '')
// Delete iframes, except those inserted by Google in lieu of video embeds
.replace(/<iframe(?![^>]*?src=("|')\S+?reader.googleusercontent.com\/reader\/embediframe.+?\1)[^>]*?>[\s\S]*?<\/iframe>/gi, '')
;
var el = /<(?:form|input|font|blink|script|style|comment|plaintext|xmp|link|listing|meta|body|frame|frameset)\b/;
var ct = 0, max = 10;
// We'll repeatedly try to strip any maliciously nested elements up to [max] times
while (el.test(str) && ct++ < max) {
str = str.replace(/<form[^>]*?>[\s\S]*?<\/form>/gi, '')
.replace(/<input[^>]*?>[\s\S]*?<\/input>/gi, '')
.replace(/<\/?(?:form|input|font|blink)[^>]*?>/gi, '')
// These are XSS/security risks
.replace(/<script[^>]*?>[\s\S]*?<\/script>/gi, '')
.replace(/<style[^>]*?>[\s\S]*?<\/style>/gi, '') // shouldn't work anyway...
.replace(/<comment[^>]*?>[\s\S]*?<\/comment>/gi, '')
.replace(/<plaintext[^>]*?>[\s\S]*?<\/plaintext>/gi, '')
.replace(/<xmp[^>]*?>[\s\S]*?<\/xmp>/gi, '')
.replace(/<\/?(?:link|listing|meta|body|frame|frameset)[^>]*?>/gi, '')
// Delete iframes, except those inserted by Google in lieu of video embeds
.replace(/<iframe(?![^>]*?src=("|')\S+?reader.googleusercontent.com\/reader\/embediframe.+?\1)[^>]*?>[\s\S]*?<\/iframe>/gi, '')
;
}
if (el.test(str)) {
// We couldn't safely strip the HTML, so we return an empty string
return '';
}
return str;
}

@@ -206,0 +224,0 @@ module.exports.stripUnsafeTags = stripUnsafeTags;

@@ -10,2 +10,22 @@ describe('resanitize', function (){

});
describe('unsafe elements', function () {
it('should strip unsafe elements', function () {
var item = require('./fixtures/unsafeElements.json');
assert.equal(resanitize(item.original), item.expected);
})
});
describe('unsafe attributes', function () {
it('should strip unsafe attributes', function () {
var items = require('./fixtures/unsafeAttributes.json');
items.forEach(function (item) {
assert.equal(resanitize(item.original), item.expected);
});
})
});
describe('comments', function () {
it('should strip comments', function () {
var item = require('./fixtures/comments.json');
assert.equal(resanitize(item.original), item.expected);
})
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc