我正在使用这样的评论系统:(我已经简化了这个问题的代码)
<?php
$status_ui = '<textarea id="box"></textarea>';
$status_ui .= '<button id="status_button" onclick="postComment(\'box\')">Post</button>';
?>
<html>
<head>
<script type="text/javascript">
function postComment(box){
var data = document.getElementById(box).value;
data = data.replace(/[^a-zA-Z0-9,.?! ;:'"]+/, '');
var hr = new XMLHttpRequest();
hr.open("POST", "comment_system.php", true);
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
hr.onreadystatechange = function() {
if(hr.readyState == 4 && hr.status == 200) {
var html_output = "";
current_html = document.getElementById("comment_list").innerHTML;
html_output += '<div class="comment">';
html_output += data;
html_output += '</div>';
document.getElementById("comment_list").innerHTML = html_output + current_html;
}
results_box.innerHTML = html_output;
}
}
hr.send("comment="+data);
</script>
</head>
<body>
<div id="container">
<?php echo $status_ui; ?>
<div id="comment_list"></div>
</div>
</body>
</html>
用户只能输入a-zA-Z0-9,。?! ;:&#39;&#34;一切都很酷。
在comment_system.php中,我正在执行各种检查,正则表达式,以便将数据安全地存储到数据库中。问题是:如何安全地将用户注释输出到comment_list div作为XSS证明?
我正在使用string.replace,我知道坏用户可以绕过它。
答案 0 :(得分:2)
html_output += '<div class="comment">';
html_output += data;
html_output += '</div>';
这是HTML注入,导致客户端跨站点脚本(DOM-XSS)漏洞。
要停止评论div中包含的有效HTML内容,请执行以下操作:
<
至<
)document.getElementById(&#34; comment_list&#34;)。innerHTML = html_output + current_html;
这是一个坏主意。每次调用它时,您都会将注释列表的全部内容序列化为新的HTML标记字符串,添加到字符串,销毁注释列表中的所有元素,以及从标记中解析新元素。这很慢并且容易出现重新编码错误,这也可能导致DOM-XSS(IE在反引号字符方面遇到问题 - 阅读innerHTML
并不一定能为您提供一个可以安全重新分配给{的字符串{1}})。
再次,通过使用DOM方法创建内容来避免这种情况:
innerHTML
(类似于结果框。)现在用户输入中可能出现的有趣字符并不重要,您将始终正确显示。因此,您可以允许用户键入一个较少的符号,而不会破坏他们的评论。
在comment_system.php中,我正在执行各种检查,正则表达式,以便将数据安全地存储到数据库中。
输入过滤有它的位置,但它不是SQL注入的答案。您应该使用查询参数化(使用mysqli或PDO)将数据导入数据库,而不是创建包含数据的查询。然后,再次,任何输入都是安全的,您可以允许用户键入撇号而不会破坏他们的评论。