在不使用XSS注入的情况下保留HTML代码



我收到用户在文本区域中写入的消息,并以以下格式保存在数据库中:

nl2br(htmlentities($_POST['message']))

利用它,我可以将/n/t转换为<br/>以保留断线。

假设我的用户编写了以下消息:

Hello World
* One
* Two
<script>alert('hello')</script>

此代码将保存在我的数据库中,但当我选择并显示此值时,该脚本将执行javascript alert

如何在没有任何XSS问题的情况下显示该消息?并保留换行符?

在存储消息之前,请考虑在消息上使用strip_tag:

// strip out tags
$store_me = strip_tags($_POST["message"]);
// this is your previous technique
$store_me = nl2br(htmlentities($store_me));

我想补充一下,你应该考虑在你的表单中添加一个跨站点请求伪造(CSRF)令牌。也就是说,在会话(或cookie)中存储一个随机生成的令牌,并将该令牌显示为表单中的隐藏输入,以便它与数据一起提交。

然后,在处理POST操作的页面中,确保CSRF令牌的POSTed值与会话(或cookie)中的值匹配。

这里有一个关于防止CSRF的SO帖子。

编辑:作为对您额外评论的回应,这里有更多信息。

您也可以使用此函数删除整个脚本,但它不会捕获每个脚本。例如,如果脚本包含"<"字符。

$str = "
Hello World
* One
* Two
<script>alert('hello')</script>
a whole bunch of data here
blah blah
and OH MY another script
<script type="text/javascript">
alert('hello');
</script>

<script type="text/javascript">
var sneaky = "<";
alert('hello');
</script> 
";

function remove_script_tags($str) {
return preg_replace('#<[^>]*script[^>]*>[^<]+</[^>]*script[^>]*>#sm', '', $str);
}
echo remove_script_tags($str) . "n";

您可以使用此函数来检测脚本,这些脚本在检测脚本尝试方面应该很好,但也可能检测到善意的帖子,就像您现在正在阅读的这篇帖子一样

function contains_script_tag($str) {
return preg_match('#<[^>]*script[^>]*>#sm', $str);
}

这两个脚本也可能捕捉到一个很长但无害的帖子,如下所示:

here is a harmless line 2 < 3
this line casually mentions "script"
oh and another harmless line 4 > 3

您应该使用filter_input(INPUT_POST, 'message', FILTER_SANITIZE_SPECIAL_CHARS);http://php.net/manual/en/function.filter-input.php

相关内容

最新更新