对于 HTML 输入,我想中和所有具有内联 js 的 HTML 元素(onclick=".."、onmouseout=".." 等)。我在想,编码以下字符还不够吗?=,(,)
所以 onclick="location.href='ggg.com'"
会变成 onclick%3D"location.href%3D'ggg.com'"
我在这里想念什么?
编辑:我确实需要接受活动的 HTML(我不能全部转义或实体是它)。
对于 HTML 输入,我想中和所有具有内联 js 的 HTML 元素(onclick=".."、onmouseout=".." 等)。我在想,编码以下字符还不够吗?=,(,)
所以 onclick="location.href='ggg.com'"
会变成 onclick%3D"location.href%3D'ggg.com'"
我在这里想念什么?
编辑:我确实需要接受活动的 HTML(我不能全部转义或实体是它)。
接受 HTML 没有简单的方法,但脚本也没有。
您必须将 HTML 解析为 DOM,删除 DOM 中所有不需要的元素和属性并生成新的 HTML。
on
* 属性不够。脚本可以嵌入到style
、src
和href
其他属性中。
如果您使用的是 PHP,请使用HTML Purifier。
您可能有几个选择...最简单的方法是将引号和可能的 <> 字符转换为它们的 HTML 编码等效项(" 等),这将导致 HTML 代码按字面意思显示。
告诉我您使用的是哪种服务器端语言,如果您愿意,我可以为您指出更多特定于语言的信息。(例如,PHP 有 htmlspecialchars()[1])。
编辑:我实际上只是阅读了您的问题。好的,您想允许 HTML 通过但不允许 JavaScript?好吧,由于我没有想到一个简单的解决方案,我建议只使用字符串替换(如果可以的话,可能是正则表达式?)来完全摆脱它们。
JavaScript 中有一组有限的事件处理程序属性。再加上对引号的需求,你可能很好。
对于概念证明,在 Perl 中,您可能会执行以下操作:
$myInput =~ s/on(mouseover|mouseout|click|focus|blur|[...])(\"[^\"]*\")|(\'[^\']*\')\s*//gi;
因此,捕获事件处理程序名称(我只包括了其中的一部分),然后是使用单引号或双引号的带引号的表达式,最后有可选的空格,并将整个内容替换为空(即删除它)。
但是,这不适用于需要更多引用级别的内容,因为最终您会回到原始分隔符。原谅人为且完全无用的示例:
onclick="eval('3+prompt("Enter a number: ")')"
在这种情况下,您可能希望编写一个循环,首先逐字解析字符串(即查找事件处理程序名称),然后逐个字符地进行,跟踪引用级别的数量并跟踪当前分隔符:
这有点费时,但理论上无论如何它都应该工作,假设 HTML 格式正确。(这是一个可怕的假设,但如果它的格式不正确,你无论如何都可以拒绝输入!)
[1] http://us3.php.net/manual/en/function.htmlspecialchars.php