Skip to content

Commit 84980c3

Browse files
committedJan 15, 2024
fix: Updated the CSS sanitizer hook demo, thanks @Steb95
1 parent 695c94f commit 84980c3

File tree

1 file changed

+28
-29
lines changed

1 file changed

+28
-29
lines changed
 

‎demos/hooks-sanitize-css-demo.html

+28-29
Original file line numberDiff line numberDiff line change
@@ -13,70 +13,69 @@
1313
/* global DOMPurify */
1414
'use strict';
1515
window.onload = function(){
16-
16+
1717
// Specify dirty HTML
18-
var dirty = document.getElementById('payload').value;
18+
let dirty = document.getElementById('payload').value;
1919

2020
// We can allow all (default elements) but SVG
21-
var config = {
21+
const config = {
2222
FORBID_TAGS: ['svg'] // SVG is not yet supported. Too messy.
2323
};
2424

25-
// Specify CSS property allow-list
26-
var allowed_properties = [
27-
'color',
25+
// Specify CSS property whitelist
26+
const allowed_properties = [
27+
'color',
2828
'background',
29-
'border',
30-
'padding',
29+
'border',
30+
'padding',
3131
'margin',
3232
'font-family',
3333
'content',
3434
'padding'
3535
];
3636

3737
// Specify if CSS functions are permitted
38-
var allow_css_functions = true;
38+
const allow_css_functions = true;
3939

4040
/**
41-
* Take CSS property-value pairs and validate against allow-list,
41+
* Take CSS property-value pairs and validate against white-list,
4242
* then add the styles to an array of property-value pairs
4343
*/
4444
function validateStyles(output, styles) {
45-
// Validate regular CSS properties
46-
for (var prop in styles) {
47-
if (typeof styles[prop] === 'string') {
48-
if (styles[prop] && allowed_properties.indexOf(prop) > -1) {
49-
if (allow_css_functions || !/\w+\(/.test(styles[prop])) {
50-
output.push(prop + ':' + styles[prop] +';');
51-
}
45+
Object.keys(styles).forEach(prop => {
46+
const value = styles[prop];
47+
if (value && typeof value === 'string') {
48+
const normalizedProp = prop.replace(/([A-Z])/g, '-$1').toLowerCase();
49+
if (allowed_properties.includes(normalizedProp) &&
50+
(allow_css_functions || !/\w+\(/.test(value))) {
51+
output.push(`${normalizedProp}:${value};`);
5252
}
5353
}
54-
}
54+
});
5555
}
5656

5757
/**
5858
* Take CSS rules and analyze them, create string wrapper to
59-
* apply them to the DOM later on. Note that only selector rules
59+
* apply them to the DOM later on. Note that only selector rules
6060
* are supported right now
6161
*/
6262
function addCSSRules(output, cssRules) {
63-
for (var index = cssRules.length-1; index >= 0; index--) {
64-
var rule = cssRules[index];
63+
Array.from(cssRules).reverse().forEach(rule => {
6564
// check for rules with selector
66-
if (rule.type == 1 && rule.selectorText) {
67-
output.push(rule.selectorText + '{')
65+
if (rule.type === 1 && rule.selectorText) {
66+
output.push(`${rule.selectorText}{`);
6867
if (rule.style) {
69-
validateStyles(output, rule.style)
68+
validateStyles(output, rule.style);
7069
}
7170
output.push('}');
7271
}
73-
}
72+
});
7473
}
7574

7675
// Add a hook to enforce CSS element sanitization
7776
DOMPurify.addHook('uponSanitizeElement', function(node, data) {
7877
if (data.tagName === 'style') {
79-
var output = [];
78+
let output = [];
8079
addCSSRules(output, node.sheet.cssRules);
8180
node.textContent = output.join("\n");
8281
}
@@ -86,13 +85,13 @@
8685
DOMPurify.addHook('afterSanitizeAttributes', function(node) {
8786
// Nasty hack to fix baseURI + CSS problems in Chrome
8887
if (!node.ownerDocument.baseURI) {
89-
var base = document.createElement('base');
88+
let base = document.createElement('base');
9089
base.href = document.baseURI;
9190
node.ownerDocument.head.appendChild(base);
9291
}
9392
// Check all style attribute values and validate them
9493
if (node.hasAttribute('style')) {
95-
var output = [];
94+
let output = [];
9695
validateStyles(output, node.style);
9796
// re-add styles in case any are left
9897
if (output.length) {
@@ -104,7 +103,7 @@
104103
});
105104

106105
// Clean HTML string and write into our DIV
107-
var clean = DOMPurify.sanitize(dirty, config);
106+
let clean = DOMPurify.sanitize(dirty, config);
108107
document.getElementById('sanitized').innerHTML = clean;
109108
}
110109
</script>

0 commit comments

Comments
 (0)
Please sign in to comment.