mirror of
https://github.com/hanzoai/DOMPurify.git
synced 2026-09-24 16:55:05 +00:00
81 lines
3.9 KiB
HTML
81 lines
3.9 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<title>DOMPurify demo: Hook to allowlist safe URI schemes</title>
|
|
<script src="../dist/purify.js"></script>
|
|
</head>
|
|
<body>
|
|
<!-- Our DIV to receive content -->
|
|
<div id="sanitized"></div>
|
|
|
|
<!-- Now let's sanitize that content -->
|
|
<script>
|
|
'use strict';
|
|
|
|
// Specify dirty HTML
|
|
const dirty = `
|
|
<a href="foo:?a">INSECURE</a>
|
|
<a href="ftp://abc.de?a">SECURE</a>
|
|
<a href="https://abc.de?a">SECURE</a>
|
|
<a href="?a">SECURE</a>
|
|
<svg><a href="ms-appx://some/app/test.html"><circle r=40 fill=red></a></svg>
|
|
<svg><a href="http://benign.com/"><circle r=40 fill=green></a></svg>
|
|
<svg><a href="#123"><circle r=40 fill=green></a></svg>
|
|
<form action="?form"><input type="submit" value="safe"></form>
|
|
<form action="bingweather:?lat=1&long=2"><input type="submit" value="unsafe"></form>
|
|
<img src="404" width="200" height="200" usemap="#test">
|
|
<map name="test"><area href="skype://123456?call" shape="rect" coords="0,0,200,200"></area></map>
|
|
<img src="404" width="200" height="200" usemap="#test">
|
|
<map name="test"><area href="http://test.com/" shape="rect" coords="0,0,200,200"></area></map>
|
|
<math href="http://test.com/">SECURE</math>
|
|
<math href="calculator:">INSECURE</math>
|
|
<math><mi target="xxx" href="http://test.com/">SECURE</mi></math>
|
|
<math><mi href="javascript:alert(1)">INSECURE</mi></math>
|
|
<math><mi target="xxx" href="aim:1111111?call">INSECURE</mi></math>
|
|
<svg xmlns:xlink="http://www.w3.org/1999/xlink"><a xlink:href="https://test.com/"><circle r=40 fill=green></a></svg>
|
|
<svg xmlns:xlink="http://www.w3.org/1999/xlink"><a xlink:href="telnet:1.1.1.1"><circle r=40 fill=red></a></svg>
|
|
<svg xmlns:xlink="http://www.w3.org/1999/xlink"><a xlink:href="?secure"><circle r=40 fill=green></a></svg>
|
|
`;
|
|
|
|
// Allowed URI schemes
|
|
const allowlist = ['http', 'https', 'ftp'];
|
|
|
|
// Build fitting regex
|
|
const regex = RegExp(`^(${allowlist.join('|')}):`, 'im');
|
|
|
|
// Add a hook to enforce URI scheme allow-list
|
|
DOMPurify.addHook('afterSanitizeAttributes', node => {
|
|
// Build an anchor to map URLs to
|
|
const anchor = document.createElement('a');
|
|
|
|
// Check all href attributes for validity
|
|
if (node.hasAttribute('href')) {
|
|
anchor.href = node.getAttribute('href');
|
|
if (anchor.protocol && !anchor.protocol.match(regex)) {
|
|
node.removeAttribute('href');
|
|
}
|
|
}
|
|
// Check all action attributes for validity
|
|
if (node.hasAttribute('action')) {
|
|
anchor.href = node.getAttribute('action');
|
|
if (anchor.protocol && !anchor.protocol.match(regex)) {
|
|
node.removeAttribute('action');
|
|
}
|
|
}
|
|
// Check all xlink:href attributes for validity
|
|
if (node.hasAttribute('xlink:href')) {
|
|
anchor.href = node.getAttribute('xlink:href');
|
|
if (anchor.protocol && !anchor.protocol.match(regex)) {
|
|
node.removeAttribute('xlink:href');
|
|
}
|
|
}
|
|
});
|
|
|
|
// Clean HTML string and write into our DIV
|
|
const clean = DOMPurify.sanitize(dirty);
|
|
document.getElementById('sanitized').innerHTML = clean;
|
|
</script>
|
|
</body>
|
|
</html>
|