我有一个表单,用户填写并发送问题,然后管理员将回答它们,最后这些问题将显示在网站上。
为了防止攻击,我使用了 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);
答案 0 :(得分:1)
如果您只想显示文字,甚至控制转换/删除哪些标签,您可以选择使用strip_tags。
echo strip_tags($title, '<p>');
在没有显示p
标记的情况下显示您的标题。
编辑:还要意识到即使允许标记,您也允许某些属性正常运行,这样就不会使您免受XSS攻击。
<p onclick="alert('xss scripting')">Awesome</p>
这仍然可行,因此建议使用HTML Purifier等过滤库。
答案 1 :(得分:1)
这不是问题,您只是没有为您的任务选择正确的功能
htmlspecialchars()
没有删除标记,它只是对它们进行转换,以便显示它们而不是执行它们。因此,例如,<p>
变为<p>
如果要(部分)删除标记,请使用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的风险。
在将它存储到数据库之前考虑使用它,这样就不需要在每个页面视图上对输入进行处理。