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

sanitize-html

Package Overview
Dependencies
Maintainers
9
Versions
114
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sanitize-html - npm Package Compare versions

Comparing version 1.19.1 to 1.19.2

5

CHANGELOG.md
## Changelog
1.19.2:
* Switched out the heavy `postcss` dependency for the lightweight `css-tree` module. No API changes. Thanks to Justin Braithwaite.
* Various doc updates. Thanks to Pulkit Aggarwal and Cody Robertson.
1.19.1:

@@ -4,0 +9,0 @@

97

dist/index.js

@@ -11,3 +11,3 @@ 'use strict';

var srcset = require('srcset');
var postcss = require('postcss');
var csstree = require('css-tree');
var url = require('url');

@@ -342,7 +342,21 @@

try {
var abstractSyntaxTree = postcss.parse(name + " {" + value + "}");
var filteredAST = filterCss(abstractSyntaxTree, options.allowedStyles);
var ast = csstree.parse(name + " {" + value + "}");
var selectors = rulesForSelector(name, options.allowedStyles || {});
value = stringifyStyleAttributes(filteredAST);
csstree.walk(ast, function (node, item, list) {
if (node.type === 'Declaration' && list) {
var value = csstree.generate(node.value);
var rules = selectors[node.property];
if (rules !== undefined && rules.every(function (rule) {
return !value.match(rule);
})) {
list.remove(item);
}
}
});
value = csstree.generate(ast).slice(name.length + 1);
value = value.slice(0, value.length - 1);
if (value.length === 0) {

@@ -352,2 +366,5 @@ delete frame.attribs[a];

}
// preserve the final semicolon
value += ';';
} catch (e) {

@@ -509,22 +526,6 @@ delete frame.attribs[a];

/**
* Filters user input css properties by whitelisted regex attributes.
*
* @param {object} abstractSyntaxTree - Object representation of CSS attributes.
* @property {array[Declaration]} abstractSyntaxTree.nodes[0] - Each object cointains prop and value key, i.e { prop: 'color', value: 'red' }.
* @param {object} allowedStyles - Keys are properties (i.e color), value is list of permitted regex rules (i.e /green/i).
* @return {object} - Abstract Syntax Tree with filtered style attributes.
*/
function filterCss(abstractSyntaxTree, allowedStyles) {
if (!allowedStyles) {
return abstractSyntaxTree;
}
var filteredAST = cloneDeep(abstractSyntaxTree);
var astRules = abstractSyntaxTree.nodes[0];
var selectedRule;
function rulesForSelector(selector, allowedStyles) {
// Merge global and tag-specific styles into new AST.
if (allowedStyles[astRules.selector] && allowedStyles['*']) {
selectedRule = mergeWith(cloneDeep(allowedStyles[astRules.selector]), allowedStyles['*'], function (objValue, srcValue) {
if (allowedStyles[selector] && allowedStyles['*']) {
return mergeWith(cloneDeep(allowedStyles[selector]), allowedStyles['*'], function (objValue, srcValue) {
if (Array.isArray(objValue)) {

@@ -534,55 +535,7 @@ return objValue.concat(srcValue);

});
} else {
selectedRule = allowedStyles[astRules.selector] || allowedStyles['*'];
}
if (selectedRule) {
filteredAST.nodes[0].nodes = astRules.nodes.reduce(filterDeclarations(selectedRule), []);
}
return filteredAST;
return allowedStyles[selector] || allowedStyles['*'] || {};
}
/**
* Extracts the style attribues from an AbstractSyntaxTree and formats those
* values in the inline style attribute format.
*
* @param {AbstractSyntaxTree} filteredAST
* @return {string} - Example: "color:yellow;text-align:center;font-family:helvetica;"
*/
function stringifyStyleAttributes(filteredAST) {
return filteredAST.nodes[0].nodes.reduce(function (extractedAttributes, attributeObject) {
extractedAttributes.push(attributeObject.prop + ':' + attributeObject.value + ';');
return extractedAttributes;
}, []).join('');
}
/**
* Filters the existing attributes for the given property. Discards any attributes
* which don't match the whitelist.
*
* @param {object} selectedRule - Example: { color: red, font-family: helvetica }
* @param {array} allowedDeclarationsList - List of declarations which pass whitelisting.
* @param {object} attributeObject - Object representing the current css property.
* @property {string} attributeObject.type - Typically 'declaration'.
* @property {string} attributeObject.prop - The CSS property, i.e 'color'.
* @property {string} attributeObject.value - The corresponding value to the css property, i.e 'red'.
* @return {function} - When used in Array.reduce, will return an array of Declaration objects
*/
function filterDeclarations(selectedRule) {
return function (allowedDeclarationsList, attributeObject) {
// If this property is whitelisted...
if (selectedRule.hasOwnProperty(attributeObject.prop)) {
var matchesRegex = selectedRule[attributeObject.prop].some(function (regularExpression) {
return regularExpression.test(attributeObject.value);
});
if (matchesRegex) {
allowedDeclarationsList.push(attributeObject);
}
}
return allowedDeclarationsList;
};
}
function filterClasses(classes, allowed) {

@@ -589,0 +542,0 @@ if (!allowed) {

{
"name": "sanitize-html",
"version": "1.19.1",
"version": "1.19.2",
"description": "Clean up user-submitted HTML, preserving whitelisted elements and whitelisted attributes on a per-element basis",

@@ -28,4 +28,5 @@ "main": "dist/index.js",

"dependencies": {
"chalk": "^2.3.0",
"htmlparser2": "^3.9.0",
"chalk": "^2.4.1",
"css-tree": "^1.0.0-alpha.29",
"htmlparser2": "^3.10.0",
"lodash.clonedeep": "^4.5.0",

@@ -35,15 +36,14 @@ "lodash.escaperegexp": "^4.1.2",

"lodash.isstring": "^4.0.1",
"lodash.mergewith": "^4.6.0",
"postcss": "^6.0.14",
"lodash.mergewith": "^4.6.1",
"srcset": "^1.0.0",
"xtend": "^4.0.0"
"xtend": "^4.0.1"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babelify": "^8.0.0",
"browserify": "^13.0.1",
"mocha": "^2.5.3",
"uglify-js": "^2.6.2"
"babel-preset-env": "^1.7.0",
"babelify": "^10.0.0",
"browserify": "^16.2.3",
"mocha": "^5.2.0",
"uglify-js": "^3.4.9"
}
}

@@ -113,3 +113,4 @@ # sanitize-html

// We don't currently allow img itself by default, but this
// would make sense if we did
// would make sense if we did. You could add srcset here,
// and if you do the URL is checked for safety
img: [ 'src' ]

@@ -123,4 +124,3 @@ },

allowedSchemesAppliedToAttributes: [ 'href', 'src', 'cite' ],
allowProtocolRelative: true,
allowedIframeHostnames: ['www.youtube.com', 'player.vimeo.com']
allowProtocolRelative: true
```

@@ -140,7 +140,7 @@

Also simple! Set your `allowedTag` and `allowedAttributes` to empty arrays (`[]`).
Also simple! Set `allowedTags` to `[]` and `allowedAttributes` to `{}`.
```js
allowedTags: [],
allowedAttributes: []
allowedAttributes: {}
```

@@ -147,0 +147,0 @@

@@ -9,3 +9,3 @@ var htmlparser = require('htmlparser2');

var srcset = require('srcset');
var postcss = require('postcss');
var csstree = require('css-tree');
var url = require('url');

@@ -303,7 +303,19 @@

try {
var abstractSyntaxTree = postcss.parse(name + " {" + value + "}");
var filteredAST = filterCss(abstractSyntaxTree, options.allowedStyles);
var ast = csstree.parse(name + " {" + value + "}");
var selectors = rulesForSelector(name, options.allowedStyles || {});
value = stringifyStyleAttributes(filteredAST);
csstree.walk(ast, function(node, item, list) {
if (node.type === 'Declaration' && list) {
var value = csstree.generate(node.value);
var rules = selectors[node.property];
if (rules !== undefined && rules.every(function (rule) { return !value.match(rule); })) {
list.remove(item)
}
}
})
value = csstree.generate(ast).slice(name.length + 1);
value = value.slice(0, value.length - 1);
if(value.length === 0) {

@@ -313,2 +325,6 @@ delete frame.attribs[a];

}
// preserve the final semicolon
value += ';';
} catch (e) {

@@ -471,23 +487,7 @@ delete frame.attribs[a];

/**
* Filters user input css properties by whitelisted regex attributes.
*
* @param {object} abstractSyntaxTree - Object representation of CSS attributes.
* @property {array[Declaration]} abstractSyntaxTree.nodes[0] - Each object cointains prop and value key, i.e { prop: 'color', value: 'red' }.
* @param {object} allowedStyles - Keys are properties (i.e color), value is list of permitted regex rules (i.e /green/i).
* @return {object} - Abstract Syntax Tree with filtered style attributes.
*/
function filterCss(abstractSyntaxTree, allowedStyles) {
if (!allowedStyles) {
return abstractSyntaxTree;
}
var filteredAST = cloneDeep(abstractSyntaxTree);
var astRules = abstractSyntaxTree.nodes[0];
var selectedRule;
function rulesForSelector(selector, allowedStyles) {
// Merge global and tag-specific styles into new AST.
if (allowedStyles[astRules.selector] && allowedStyles['*']) {
selectedRule = mergeWith(
cloneDeep(allowedStyles[astRules.selector]),
if (allowedStyles[selector] && allowedStyles['*']) {
return mergeWith(
cloneDeep(allowedStyles[selector]),
allowedStyles['*'],

@@ -500,59 +500,7 @@ function(objValue, srcValue) {

);
} else {
selectedRule = allowedStyles[astRules.selector] || allowedStyles['*'];
}
if (selectedRule) {
filteredAST.nodes[0].nodes = astRules.nodes.reduce(filterDeclarations(selectedRule), []);
}
return filteredAST;
return allowedStyles[selector] || allowedStyles['*'] || {};
}
/**
* Extracts the style attribues from an AbstractSyntaxTree and formats those
* values in the inline style attribute format.
*
* @param {AbstractSyntaxTree} filteredAST
* @return {string} - Example: "color:yellow;text-align:center;font-family:helvetica;"
*/
function stringifyStyleAttributes(filteredAST) {
return filteredAST.nodes[0].nodes
.reduce(function(extractedAttributes, attributeObject) {
extractedAttributes.push(
attributeObject.prop + ':' + attributeObject.value + ';'
);
return extractedAttributes;
}, [])
.join('');
}
/**
* Filters the existing attributes for the given property. Discards any attributes
* which don't match the whitelist.
*
* @param {object} selectedRule - Example: { color: red, font-family: helvetica }
* @param {array} allowedDeclarationsList - List of declarations which pass whitelisting.
* @param {object} attributeObject - Object representing the current css property.
* @property {string} attributeObject.type - Typically 'declaration'.
* @property {string} attributeObject.prop - The CSS property, i.e 'color'.
* @property {string} attributeObject.value - The corresponding value to the css property, i.e 'red'.
* @return {function} - When used in Array.reduce, will return an array of Declaration objects
*/
function filterDeclarations(selectedRule) {
return function (allowedDeclarationsList, attributeObject) {
// If this property is whitelisted...
if (selectedRule.hasOwnProperty(attributeObject.prop)) {
var matchesRegex = selectedRule[attributeObject.prop].some(function(regularExpression) {
return regularExpression.test(attributeObject.value);
});
if (matchesRegex) {
allowedDeclarationsList.push(attributeObject);
}
}
return allowedDeclarationsList;
};
}
function filterClasses(classes, allowed) {

@@ -559,0 +507,0 @@ if (!allowed) {

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

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