从没有XSS漏洞的数据库中读取HTML标记

时间:2014-12-24 05:55:55

标签: php html xss

我有一个简单的评论部分,我希望能够为每个评论设置样式,将文本和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样式(就像你在这些评论中看到的那样)。

非常感谢!

3 个答案:

答案 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>.

http://php.net/strip_tags

答案 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

将运行:

XSS is a running

除了之外,您还应该在输出用户控制的文本的任何页面上实施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清理程序,因此您仍然应该首先运行所有用户提供的输入。