我有一个简单的评论部分,我希望能够为每个评论设置样式,将文本和html标签保存在数据库中。
在大多数情况下,我对将注释数据插入数据库的方式充满信心。当然,如果您不这样认为,我并不反对听取您的意见。
if(isset($_POST["comment"])) {
$userid = $_SESSION['user_id'];
$comment = $conn->real_escape_string(trim($_POST['comment']));
$sql = "INSERT INTO comments (`user_id`, `comment`, `parent_id`, `type`)
VALUES ('.$userid.', '$comment', '$parent_id', '$type')";
if ($conn->query($sql) === TRUE) {
echo "Thanks for the comment!";
} else {
die("Error commenting" . $conn->error);
}
}
但是,如果我直接通过MySQL并将行更新为简单的javascript警报,它会呈现并在页面加载时收到警报。因此,我在阅读数据时遇到了漏洞。
while($row = mysqli_fetch_array($result)) {
$parent_id = $row['parent_id'];
$type = $row['type'];
echo '<h1>'.$row['user_name'].'</h1>';
echo '<p>'.$row['comment'].'</p>';
}
我知道我可以通过像strip_tags($row['comment'])
这样的东西使这更安全。但是,如果我这样做,则评论中不会有任何样式,因为<p>
标记(以及其他标记)将被剥离。因此,我的问题是:如何以一种防止明显的XSS漏洞的方式读取数据,同时允许简单的html样式(就像你在这些评论中看到的那样)。
非常感谢!
答案 0 :(得分:1)
首先,您可以在评论系统中使用无害bbcode
,但我认为您并不理解strip_tags()
。 strip_tags()
有两个论点。第一个是你的字符串,但第二个是允许的标签(可以通过strip_tags()
的标签)所以它就像这样:
<?php
$text = '<p>Test texts.</p><!-- Comment --> <a href="#fragment">and other text</a>';
echo strip_tags($text);
# Allow <p> and <a>
echo strip_tags($text, '<p><a>');
?>
并输出:
<p>Test texts.</p> <a href="#fragment">and other text</a>
您可以使用strip_tags()
文档here
答案 1 :(得分:0)
strip_tags()
有第二个参数,它是一串允许的标记。
在这种情况下,将删除所有标签:
$comment = "<script>alert('Hello world');</script>This is <i>a comment</i>.";
$strippedComment = strip_tags($comment);
echo $comment;
这会导致:alert('Hello world');This is a comment.
但是,使用第二个参数,您可以允许基本的格式化标记,如下所示:
$comment = "<script>alert('Hello world');</script>This is <i>a comment</i>.";
$strippedComment = strip_tags($comment, "<i><u><b>");
echo $comment;
现在会产生:alert('Hello world');This is <i>a comment</i>.
答案 2 :(得分:0)
不幸的是,其他答案都是错误的:使用strip_tags
不安全。
原因?
用户只需输入这样的代码即可绕过您的清理工作:
<p onmouseover="alert('This could be evil XSS')">Test texts.</p> <a href="#fragment">and other text</a>
通过允许strip_tags
代码的<p>
传递此代码不会删除代码:
echo strip_tags("<p onmouseover=\"alert('This could be evil XSS')\">Test texts.</p> <a href=\"#fragment\">and other text</a>", "<p>");
仍然输出p
的属性:
<p onmouseover="alert('This could be evil XSS')">Test texts.</p> and other text
将运行:
除了之外,您还应该在输出用户控制的文本的任何页面上实施Content Security Policy ,使用HTML Purifier等清理程序使文本对HTML输出安全。这应该可以有效地防止注入的脚本命令运行。
CSP允许您有效地阻止内联脚本被浏览器执行。它目前是supported by现代浏览器,例如Chrome和Firefox(尽管IE目前只有部分支持)。
这是通过页面中的HTTP响应标头完成的。
e.g。
Content-Security-Policy: script-src 'self' https://apis.google.com
如果用户设法将JavaScript注入到您的页面中,将停止执行内联JavaScript(它会被警告忽略),但会允许脚本标记引用您自己的服务器或https://apis.google.com
。这可以根据需要定制。对于不支持CSP的浏览器,仍然需要HTML清理程序,因此您仍然应该首先运行所有用户提供的输入。