You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

sanitize-html

Package Overview
Dependencies
Maintainers
4
Versions
120
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
2.17.0
to
2.17.1
+83
-39
index.js

@@ -91,3 +91,4 @@ const htmlparser = require('htmlparser2');

let result = '';
// Used for hot swapping the result variable with an empty string in order to "capture" the text written to it.
// Used for hot swapping the result variable with an empty string
// in order to "capture" the text written to it.
let tempResult = '';

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

const tagAllowed = function (name) {
return options.allowedTags === false || (options.allowedTags || []).indexOf(name) > -1;
return options.allowedTags === false ||
(options.allowedTags || []).indexOf(name) > -1;
};

@@ -306,3 +308,4 @@

const isBeingEscaped = skip && (options.disallowedTagsMode === 'escape' || options.disallowedTagsMode === 'recursiveEscape');
const shouldPreserveEscapedAttributes = isBeingEscaped && options.preserveEscapedAttributes;
const shouldPreserveEscapedAttributes = isBeingEscaped &&
options.preserveEscapedAttributes;

@@ -321,4 +324,6 @@ if (shouldPreserveEscapedAttributes) {

}
// If the value is empty, check if the attribute is in the allowedEmptyAttributes array.
// If it is not in the allowedEmptyAttributes array, and it is a known non-boolean attribute, delete it
// If the value is empty, check if the attribute is
// in the allowedEmptyAttributes array.
// If it is not in the allowedEmptyAttributes array,
// and it is a known non-boolean attribute, delete it
// List taken from https://html.spec.whatwg.org/multipage/indices.html#attributes-3

@@ -334,5 +339,7 @@ if (value === '' && (!options.allowedEmptyAttributes.includes(a)) &&

if (!allowedAttributesMap ||
(has(allowedAttributesMap, name) && allowedAttributesMap[name].indexOf(a) !== -1) ||
(has(allowedAttributesMap, name) &&
allowedAttributesMap[name].indexOf(a) !== -1) ||
(allowedAttributesMap['*'] && allowedAttributesMap['*'].indexOf(a) !== -1) ||
(has(allowedAttributesGlobMap, name) && allowedAttributesGlobMap[name].test(a)) ||
(has(allowedAttributesGlobMap, name) &&
allowedAttributesGlobMap[name].test(a)) ||
(allowedAttributesGlobMap['*'] && allowedAttributesGlobMap['*'].test(a))) {

@@ -381,8 +388,10 @@ passedAllowedAttributesMapCheck = true;

if (options.allowedScriptHostnames || options.allowedScriptDomains) {
const allowedHostname = (options.allowedScriptHostnames || []).find(function (hostname) {
return hostname === parsed.url.hostname;
});
const allowedDomain = (options.allowedScriptDomains || []).find(function(domain) {
return parsed.url.hostname === domain || parsed.url.hostname.endsWith(`.${domain}`);
});
const allowedHostname = (options.allowedScriptHostnames || [])
.find(function (hostname) {
return hostname === parsed.url.hostname;
});
const allowedDomain = (options.allowedScriptDomains || [])
.find(function(domain) {
return parsed.url.hostname === domain || parsed.url.hostname.endsWith(`.${domain}`);
});
allowed = allowedHostname || allowedDomain;

@@ -411,9 +420,14 @@ }

: (!options.allowedIframeHostnames && !options.allowedIframeDomains);
} else if (options.allowedIframeHostnames || options.allowedIframeDomains) {
const allowedHostname = (options.allowedIframeHostnames || []).find(function (hostname) {
return hostname === parsed.url.hostname;
});
const allowedDomain = (options.allowedIframeDomains || []).find(function(domain) {
return parsed.url.hostname === domain || parsed.url.hostname.endsWith(`.${domain}`);
});
} else if (
options.allowedIframeHostnames ||
options.allowedIframeDomains
) {
const allowedHostname = (options.allowedIframeHostnames || [])
.find(function (hostname) {
return hostname === parsed.url.hostname;
});
const allowedDomain = (options.allowedIframeDomains || [])
.find(function(domain) {
return parsed.url.hostname === domain || parsed.url.hostname.endsWith(`.${domain}`);
});
allowed = allowedHostname || allowedDomain;

@@ -472,5 +486,13 @@ }

if (allowedSpecificClasses && allowedWildcardClasses) {
value = filterClasses(value, deepmerge(allowedSpecificClasses, allowedWildcardClasses), allowedClassesGlobs);
value = filterClasses(
value,
deepmerge(allowedSpecificClasses, allowedWildcardClasses),
allowedClassesGlobs
);
} else {
value = filterClasses(value, allowedSpecificClasses || allowedWildcardClasses, allowedClassesGlobs);
value = filterClasses(
value,
allowedSpecificClasses || allowedWildcardClasses,
allowedClassesGlobs
);
}

@@ -486,3 +508,6 @@ if (!value.length) {

const abstractSyntaxTree = postcssParse(name + ' {' + value + '}', { map: false });
const filteredAST = filterCss(abstractSyntaxTree, options.allowedStyles);
const filteredAST = filterCss(
abstractSyntaxTree,
options.allowedStyles
);

@@ -620,3 +645,4 @@ value = stringifyStyleAttributes(filteredAST);

// remove the opening tag from the result
result = result.substring(0, frame.tagPosition) + result.substring(frame.tagPosition + frame.openingTagLength);
result = result.substring(0, frame.tagPosition) +
result.substring(frame.tagPosition + frame.openingTagLength);
return;

@@ -656,2 +682,12 @@ } else if (filterResult) {

if (options.disallowedTagsMode === 'escape' || options.disallowedTagsMode === 'recursiveEscape') {
const lastParsedIndex = parser.endIndex;
if (lastParsedIndex != null && lastParsedIndex >= 0 && lastParsedIndex < html.length) {
const unparsed = html.substring(lastParsedIndex);
result += escapeHtml(unparsed);
} else if ((lastParsedIndex == null || lastParsedIndex < 0) && html.length > 0 && result === '') {
result = escapeHtml(html);
}
}
return result;

@@ -767,4 +803,6 @@

* @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).
* @property {array[Declaration]} abstractSyntaxTree.nodes[0] -
* Each object contains 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} - The modified tree.

@@ -791,3 +829,4 @@ */

if (selectedRule) {
abstractSyntaxTree.nodes[0].nodes = astRules.nodes.reduce(filterDeclarations(selectedRule), []);
abstractSyntaxTree.nodes[0].nodes = astRules.nodes
.reduce(filterDeclarations(selectedRule), []);
}

@@ -803,3 +842,4 @@

* @param {AbstractSyntaxTree} filteredAST
* @return {string} - Example: "color:yellow;text-align:center !important;font-family:helvetica;"
* @return {string} - Example:
* "color:yellow;text-align:center !important;font-family:helvetica;"
*/

@@ -821,9 +861,12 @@ function stringifyStyleAttributes(filteredAST) {

*
* @param {object} selectedRule - Example: { color: red, font-family: helvetica }
* @param {array} allowedDeclarationsList - List of declarations which pass the allowlist.
* @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
* @param {object} selectedRule - Example: { color: red, font-family: helvetica }
* @param {array} allowedDeclarationsList - List of declarations
* which pass the allowlist.
* @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
*/

@@ -834,5 +877,6 @@ function filterDeclarations(selectedRule) {

if (has(selectedRule, attributeObject.prop)) {
const matchesRegex = selectedRule[attributeObject.prop].some(function(regularExpression) {
return regularExpression.test(attributeObject.value);
});
const matchesRegex = selectedRule[attributeObject.prop]
.some(function(regularExpression) {
return regularExpression.test(attributeObject.value);
});

@@ -969,5 +1013,5 @@ if (matchesRegex) {

tagName: newTagName,
attribs: attribs
attribs
};
};
};
{
"name": "sanitize-html",
"version": "2.17.0",
"version": "2.17.1",
"description": "Clean up user-submitted HTML, preserving allowlisted elements and allowlisted attributes on a per-element basis",

@@ -10,9 +10,8 @@ "sideEffects": false,

],
"scripts": {
"test": "npx eslint . && mocha test/test.js"
},
"repository": {
"type": "git",
"url": "https://github.com/apostrophecms/sanitize-html.git"
"url": "https://github.com/apostrophecms/apostrophe.git",
"directory": "packages/sanitize-html"
},
"homepage": "https://github.com/apostrophecms/apostrophe/tree/main/packages/sanitize-html#readme",
"keywords": [

@@ -35,12 +34,14 @@ "html",

"devDependencies": {
"eslint": "^7.3.1",
"eslint-config-apostrophe": "^3.4.0",
"eslint-config-standard": "^14.1.1",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"eslint": "^9.39.1",
"mocha": "^10.2.0",
"sinon": "^9.0.2"
"sinon": "^9.0.2",
"eslint-config-apostrophe": "^6.0.2"
},
"apostropheTestConfig": {
"requiresMongo": false
},
"scripts": {
"test": "npm run lint && mocha",
"lint": "eslint ."
}
}