PHP中严格的HTML验证和筛选


Strict HTML Validation and Filtering in PHP

我正在寻找对用户提交的HTML执行严格(白名单)验证/过滤的最佳实践。

主要目的是过滤掉可能通过web表单输入的XSS和类似的垃圾。次要目的是限制非技术用户输入的HTML内容的破坏,例如通过具有HTML视图的所见即所得编辑器。

我正在考虑使用HTML净化器,或者通过使用HTML DOM解析器来完成类似HTML(脏)->DOM(脏)->过滤器->DOM(干净)->HTML(干净)的过程。

你能描述一下这些或任何更简单的有效策略的成功吗?有什么需要注意的陷阱吗?

我已经在HTML净化器上测试了我所知道的所有漏洞,它做得很好。它不仅过滤HTML,还过滤CSS和URL。

一旦您将元素和属性缩小到无辜的元素和属性,陷阱就出现在属性内容中——javascript:伪URL(IE允许协议名称中的制表符——java	script:仍然有效)和触发JS的CSS属性中。

解析URL可能很棘手,例如这些是有效的:http://spoof.com:xxx@evil.com//evil.com。国际化域(IDN)可以用两种方式编写——Unicode和punycode。

使用HTML净化器——它已经解决了大部分问题。如果你只想修复损坏的HTML,那么就使用HTMLTidy(它可以作为PHP扩展)。

用户提交的HTML并不总是有效的,甚至不完整。浏览器会解释大量无效的HTML,你应该确保你能捕捉到它

还要注意有效的外观:

<img src="http://www.mysite.com/logout" />

<a href="javascript:alert('xss hole');">click</a>

我成功地使用了HTML净化器,并且没有任何xs或其他不需要的输入过滤器。我还通过Tidy扩展运行了净化HTML,以确保它也能验证。

W3C有一个用于验证HTML的大型开源软件包:

http://validator.w3.org/

你可以自己下载软件包,并可能实现他们正在做的任何事情。不幸的是,似乎很多DOM解析器都愿意改变规则,"在野外"分配HTML代码,所以让大师告诉你哪里出了问题,而不是把它留给更实用的工具是个好主意——有很多网站不是完美的、兼容的HTML,但我们仍然每天都在使用。