消毒膏输入

时间:2015-05-20 05:23:05

标签: javascript copy-paste contenteditable

假设我复制了一些“恶意”输入,比如带有事件处理程序或其他javascript的DOM节点

<img src="bunny.jpg" onload="alert('hi');">

如果我将其复制到剪贴板并将其粘贴到contenteditable div中,则会彻底删除事件处理程序。

<img src="/Users/tjhance/Desktop/bunny.jpg">

我现在可以操纵这个DOM节点到我的内心了。至于好。

另一方面,假设我想挂钩浏览器的粘贴事件并以我自己的方式处理粘贴。我可以轻松获取剪贴板数据:

<div contenteditable="true" id="myContentEditableDiv"></div>

<script>

$('#myContentEditableDiv').on('paste', function(event) {
    console.log(event);
    var pastedHtml = event.originalEvent.clipboardData.getData('text/html');
    console.log(pastedHtml);
});

</script>

当我进行粘贴时,我会得到HTML

<meta charset='utf-8'><img src="/Users/tjhance/Desktop/bunny.jpg" onload="alert('hi');" style="color: rgb(0, 0, 0); font-family: Times; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px; -webkit-text-stroke-width: 0px;">

它是未经过清理的,并且仍然有事件监听器。据我所知,我对这个字符串做不了什么。我无法使用浏览器将其解析为HTML,因为它会运行JavaScript,这是一个巨大的安全漏洞。

很明显,浏览器有一些清理HTML的功能,因为它在粘贴时就可以实现。因此,如果我想要干净的HTML,我可以等待事件通过并将HTML添加到DOM。当然,如果我能做到这一点,我就不会在这里张贴......

所以我的问题是,有没有什么方法可以采用可能脏的HTML并获得干净,安全的DOM节点来使用浏览器DOM api进行操作,而不必让浏览器实际将HTML粘贴到contenteditable div中(用户可以看到)?我有什么选择?

1 个答案:

答案 0 :(得分:1)

您可以在所有浏览器支持获取剪贴板数据之前的前几天使用this hacky technique,尽管它不是很好。最大的缺点是它只能通过键盘粘贴。

另一种方法是自己清理HTML字符串。我作为起点出现的选项是DOMParserdocument.implementation.createHTMLDocument。我不确定他们有多安全;快速搜索发现:

https://security.stackexchange.com/questions/50970/is-it-safe-to-use-createhtmldocument-to-sanitize-html