4

对于 HTML 输入,我想中和所有具有内联 js 的 HTML 元素(onclick=".."、onmouseout=".." 等)。我在想,编码以下字符还不够吗?=,(,)

所以 onclick="location.href='ggg.com'"
会变成 onclick%3D"location.href%3D'ggg.com'"

我在这里想念什么?

编辑:我确实需要接受活动的 HTML(我不能全部转义或实体是它)。

4

2 回答 2

2

接受 HTML 没有简单的方法,但脚本也没有。

您必须将 HTML 解析为 DOM,删除 DOM 中所有不需要的元素和属性并生成新的 HTML。

它不能用正则表达式可靠地完成

on* 属性不够。脚本可以嵌入到stylesrchref其他属性中。

如果您使用的是 PHP,请使用HTML Purifier

于 2009-08-25T14:54:50.243 回答
0

您可能有几个选择...最简单的方法是将引号和可能的 <> 字符转换为它们的 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: ")')"

在这种情况下,您可能希望编写一个循环,首先逐字解析字符串(即查找事件处理程序名称),然后逐个字符地进行,跟踪引用级别的数量并跟踪当前分隔符:

  1. 标记处理程序名称开头的索引(onclick 中的“o”等)
  2. 从引用级别 0 开始(或在您处理了起始引号分隔符后为 1)。
  3. 如果当前定界符是 " 并且您看到 ',则将引用级别增加 1 并将当前定界符切换为 '。
  4. 如果当前分隔符是“并且您看到了”,则将引用级别降低 1 并将当前分隔符切换为 '。
  5. 如果当前分隔符是 ' 并且您看到 ",则将引用级别增加 1 并将当前分隔符切换为 '。
  6. 如果当前定界符是 ' 并且您看到 ',则将引用级别降低 1 并将当前定界符切换为 '。
  7. 如果引用级别回到 0,那么您的字符串已经结束。标记字符串结束位置的索引。
  8. 使用字符串操作函数将子字符串从第一个索引剪切到最后一个索引。

这有点费时,但理论上无论如何它都应该工作,假设 HTML 格式正确。(这是一个可怕的假设,但如果它的格式不正确,你无论如何都可以拒绝输入!)

[1] http://us3.php.net/manual/en/function.htmlspecialchars.php

于 2009-08-11T04:12:47.320 回答