-
-
Notifications
You must be signed in to change notification settings - Fork 727
/
hooks-mentaljs-demo.html
84 lines (78 loc) · 3.48 KB
/
hooks-mentaljs-demo.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<!doctype html>
<html>
<head>
<script src="../dist/purify.js"></script>
<!-- Grab the latest version of MentalJS -->
<script src="./lib/Mental.js"></script>
</head>
<body>
<!-- Our DIV to receive content -->
<div id="sanitized"></div>
<div id="test"></div>
<!-- Now let's sanitize that content -->
<script>
'use strict';
// Initialize MentalJS
MentalJS().init({ dom: true, parseInnerHTML: filter });
// Specify dirty HTML
const dirty = `
abc<script>alert('from script:'+location)<\/script>
<img src="xyz" onerror="document.getElementById('test').innerHTML='<img src=123 onerror=alert(/from_innerhtml/);';" />
<img src="xyz" onerror="alert('from img:'+location)">
<img src="xyz" onload="alert\`3\`">
<img src="xyz" onload="">
<script src=//evil.com><\/script>
<script>alert\`4\`<\/script>
<script src=//evil.com>alert(5)<\/script>
<svg><script xlink:href=//evil.com>alert(6)<\/script></svg>
<svg><script href="//evil.com">123<\/script><p>
`;
// Add a hook to sanitize all script content with MentalJS
DOMPurify.addHook('uponSanitizeElement', (node, data) => {
if (data.tagName === 'script') {
const script = node.textContent;
if (!script || 'src' in node.attributes
|| 'href' in node.attributes
|| 'xlink:href' in node.attributes) {
return node.parentNode.removeChild(node);
}
try {
const mental = MentalJS().parse({
options: { eval: false, dom: false },
code: script
});
const scriptNode = document.createElement('script');
scriptNode.appendChild(document.createTextNode(mental));
document.head.appendChild(scriptNode);
return node.parentNode.removeChild(node);
} catch (e) {
return node.parentNode.removeChild(node);
}
}
});
// Add a hook to sanitize all allow-listed events with MentalJS
DOMPurify.addHook('uponSanitizeAttribute', (node, data) => {
if (data.attrName.match(/^on\w+/)) {
const script = data.attrValue;
try {
return data.attrValue = MentalJS().parse({
options: { eval: false, dom: false },
code: script
});
} catch (e) {
return data.attrValue = '';
}
}
});
function filter(dirty) {
const config = {
ADD_TAGS: ['script'],
ADD_ATTR: ['onclick', 'onmouseover', 'onload', 'onunload', 'onerror']
};
const clean = DOMPurify.sanitize(dirty, config);
return clean;
}
document.getElementById('sanitized').innerHTML = filter(dirty);
</script>
</body>
</html>