Sanitize HTML
12.22'21
对于未知的 HTML 字符串,如果需要在页面渲染,必须要先过滤(sanitize),以预防 XSS(Cross-site scripting)
目标
假设用户输入了可能执行的脚步,例如 <img onerror="alert(1)" src="abc" />
,我们需要能过滤掉 onerror
属性。
实现
建立 tag 和 attribute 的白名单,基于输入的 HTML 字符串建立 DOM 树,遍历后生成安全的 HTML 字符串。
那么如何基于 HTML 字符串获得对应的 DOM 树呢?
使用 DOMParser
https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
const parser = new DOMParser()
const doc = parser.parseFromString(htmlString, 'text/html')
遍历和复制
遍历树上每个节点,复制安全的属性到新的树节点
大致的流程
const node = doc.body
const newNode = doc.createElement(node.tagName)
Array.from(node.attributes).forEach(({ name, value }) => {
// For style
if (name === 'style') {
Array.from(node.style).forEach(styleName => {
// Filter styleName
newNode.style.setProperty(
styleName,
node.style.getPropertyValue(styleName)
)
})
} else {
// Filter attribute
// Check URI attribute
// ...
newNode.setAttribute(name, value)
}
})
// Recursively node.childNodes
📖