PHP htmlspecialchars()函数在页面中显示html安全标记

时间:2014-08-12 11:52:29

标签: php html tags xss htmlspecialchars

我有一个表单,用户填写并发送问题,然后管理员将回答它们,最后这些问题将显示在网站上。
为了防止攻击,我使用了 PDO htmlspecialchars()功能。我不对输入数据应用任何更改,只使用PDO存储它们。但是当我想在页面中显示它们时,我使用htmlspecialchars()。但这导致偶然<p>标签作为其中的一部分出现在文本中。有什么问题,如何解决?

存储问题:

$stmt = "INSERT INTO tbl_questions (title,question) VALUES (?,?)";  
$q = $db->prepare($stmt);
$q->execute(array($_POST['title'],$_POST['question']));

显示问题:

echo htmlspecialchars($title).'<br />'.htmlspecialchars($question);

3 个答案:

答案 0 :(得分:1)

如果您只想显示文字,甚至控制转换/删除哪些标签,您可以选择使用strip_tags

echo strip_tags($title, '<p>');

在没有显示p标记的情况下显示您的标题。

编辑:还要意识到即使允许标记,您也允许某些属性正常运行,这样就不会使您免受XSS攻击。

<p onclick="alert('xss scripting')">Awesome</p>

这仍然可行,因此建议使用HTML Purifier等过滤库。

答案 1 :(得分:1)

这不是问题,您只是没有为您的任务选择正确的功能 htmlspecialchars()没有删除标记,它只是对它们进行转换,以便显示它们而不是执行它们。因此,例如,<p>变为&lt;p&gt; 如果要(部分)删除标记,请使用strip_tags()功能。而且,如果您不需要这些标签,您可以(并且应该,我认为)在将您的内容添加到数据库之前剥离它们 而且,您可以允许某些标记,如下所示:

$q->execute(array(strip_tags($_POST['title']), strip_tags($_POST['question'], "<br><em>"));

这样您就可以在问题中考虑<br><em>。这不是必需的,我只是向您展示该功能的可能性。

但是,如果您想使用更灵活的规则,我建议您使用HTML清理程序。例如,我使用HTMLawed。它不仅允许指定允许的标记,还允许指定包含通配符的属性和类(例如,您可以删除除class属性之外的任何内容,或允许除style属性之外的所有内容。

答案 2 :(得分:1)

方法htmlspecialchars并不完美。

看看htmlpurifier。它通过白名单过滤器更强大。有了它,您的用户可以编写html(例如<p>),并且您没有XSS的风险。

在将它存储到数据库之前考虑使用它,这样就不需要在每个页面视图上对输入进行处理。