如何安全地输出包含HTML标签的内容?
我有一个博客系统,用户必须输入html文本区域的内容,包括html标签,如<p>
。这存储在数据库中。如果这个输入然后用php回显到一个网页,我怎么可以逃避输出来防止XSS,但保留html标签的含义,以便博客文章格式正确?如果我使用htmlentities($blog_content)
,它会将html标签打印到页面上,因此您会看到<p>hello this is a blog</p>
。如何安全地输出包含HTML标签的内容?
这可能吗?
你想要的是选择性过滤或消毒。换句话说,您希望允许一些 HTML,但不允许其他恶意标记。这是非常棘手的事情,尤其是因为HTML语法非常复杂,过于简单的清理尝试容易出错,从而无论如何都可以通过格式错误的HTML注入标记。
如果可能,您应该远离让用户提交HTML。使用Wiki标记,Markdown,BBcode或类似的特殊标记语言。
如果您确定自己在做什么,您应该选择一个经过良好测试的,功能强大的库,以提供此类清理功能。 HTML Purifier是我认识的唯一适合此描述的人。
最好的解决方案。对于自己回答这个问题犹豫不决,因为他们似乎已经接受了HTML,我不想提出改变建议。但是,如果使用其他标记语言是可行的 - 那就做吧。 – 2013-02-11 16:25:41
谢谢,HTML Purifier在这种情况下似乎是最好的解决方案。由于输入数据的能力将在密码保护区内,并且仅限于极少数用户,因此我很高兴他们能够输入html。 – 2013-02-11 16:49:44
嗯,你可以只剥除<script>
标签,使用strip_tags()
这不是防弹的解决方案,但你可以通过只允许提高安全一些标签(基本上粗体,斜体,链接和一些更多)...
然后,您可以轻松打印您的内容并避免执行JavaScript。
$text = '<p>Test paragraph.</p><!-- Comment --> <a href="#fragment">Other text</a>';
echo strip_tags($text);
echo "\n";
// Allow <p>, <a> and some formatting
echo strip_tags($text, '<p><a><i><em><b><strong>');
**这部分不是防弹解决方案**你错过了吗? :) – Napolux 2013-02-11 16:21:45
你提到你可以“通过允许一些标签来提高安全性”,这是不真实的。通过实施允许标签的白名单,您根本没有提高安全性。你也提到你可以“避免JavaScript执行”,你不能用这种方法。只是为了一个旁注:downvote不是从我。别生气。我只是建议改进。 – 2013-02-11 16:22:42
你可以使用strip_tags()
,并允许一些HTML元素:
echo strip_tags($text, '<p><a>');
然而,这仍是危险的,因为有人能像
<p onclick="doSomething();">...</p>
插入代码,那么这将是最好的,如果您可以使用DOMDocument的loadHtml()
方法从数据库加载数据。然后你必须遍历节点并检查是否有任何属性或节点可能需要删除,例如通过使用DOMNode::hasAttributes
和DOMNode::hasChildNodes
。
这是正确答案,是'strip_tags'和'DOMDocument'的组合。我在这里唯一的建议是实施允许标记的白名单,而不是黑名单(以防万一您错过了某些内容)。这里的重要提示是如果HTML格式不正确,则不允许发布帖子。否则,任何逻辑都可能破坏格式错误的HTML。 – 2013-02-11 16:23:29
你测试过htmlentities()吗? – 2013-02-11 16:18:04
[PHP XSS预防白名单](http://stackoverflow.com/questions/2992674/php-xss-prevention-whitelisting) – Quentin 2013-02-11 16:21:18