【发布时间】:2020-12-15 01:58:20
【问题描述】:
在我必须为学校做的一个项目中,它需要防止我的网站上的 XSS(跨站点脚本)攻击,所以标签如 <script type="text/javascript">alert("hello");</script>(我可以在我的网站的每个输入标签中插入)应该'不起作用(在这种情况下我不应该看到警报窗口)。在学校,有人建议我使用 php 函数 htmlspecialchars,但当我在网站的评论中插入此标签时,浏览器仍会显示警报窗口。我不明白我做错了什么。
(注意:我也插入了js代码,但我认为问题出在php上,所有代码都能正常工作)
$("#new-comment").on('click',function(){
var $newReview = $("<input class='new-input' type='text' id='insert' name='insert' placeholder='write here...'>");
$("#reviews").append($newReview);
$newReview.on('keypress',function(e){
if(e.which == 13){
var comm = $(this);
var datatime = new Date($.now());
correctHour = printMysqlFormat(datatime);
$.ajax({
url:'reviews/reviews_query.php',
data: {put:true, title: $("#right_title").text(), script: comm.val(), time: correctHour},
datatype:'json',
success: function(json){
var output = jQuery.parseJSON(json);
var newName = "<span class='rev_name'>"+ output + "</span>";
var newComment = "<span class='rev_comment'>"+ comm.val() + "<div class='rev_time'>" + correctHour + "</div></span>";
$("#reviews > ul").html($("#reviews > ul").html()+"<li style='margin-bottom:20px'>" + newName + " " + newComment + "</li>");
},
error: function(e){
console.log(e.message);
}
});
$newReview.remove();
}
});
});
if(isset($_GET["show"]) && isset($_GET["title"])){ //to show all comments
$db = new PDO("mysql:host=localhost;dbname=music", "username", "password");
$titolo = $_GET["title"];
$ti = $db->quote($titolo);
$rows = $db->query("SELECT * FROM reviews WHERE titolo=$ti ORDER BY ora ASC");
if($rows->rowCount() == 0){
echo 0;
}else{
$res = $rows->fetchALL(PDO::FETCH_ASSOC);
echo json_encode($res);
}
}
if(isset($_GET["put"]) && isset($_GET["title"]) && isset($_GET["script"]) && isset($_GET["time"])){ //to write a new comment
$db = new PDO("mysql:host=localhost;dbname=music", "username", "password");
$username = $_SESSION["name"];
$us = $db->quote($username);
$titolo = $_GET["title"];
$ti = $db->quote($titolo);
$commento = $_GET["script"];
$commento = htmlspecialchars($commento);
$comm = $db->quote($commento);
$timestamp = $_GET["time"];
$tim = $db->quote($timestamp);
$rows = $db->query("INSERT into reviews VALUES ($us, $ti, $comm, $tim)");
$res = $_SESSION["name"];
echo json_encode($res);
}
编辑:我已尝试使用此代码,但没有任何变化:
if(isset($_GET["show"]) && isset($_GET["title"])){
$db = new PDO("mysql:host=localhost;dbname=music", "username", "password");
$titolo = $_GET["title"];
$ti = $db->quote($titolo);
$rows = $db->query("SELECT * FROM reviews WHERE titolo=$ti ORDER BY ora ASC");
if($rows->rowCount() == 0){
echo 0;
}else{
$res = $rows->fetchALL(PDO::FETCH_ASSOC);
$res['comment_clean'] = htmlspecialchars($res['commento'], ENT_QUOTES, 'UTF-8'); //commento is an attribute of my table, where I save the comment
echo json_encode($res);
}
}
【问题讨论】:
-
请注意:虽然您可能已经(尝试)保护它免受脚本注入,但您未能充分保护它免受 SQL 注入。
-
嗯,你的老师错了,你应该让他/她知道。
-
无论如何关于脚本注入...我可以在您的“成功”功能中看到您正在执行
newComment = "<span class='rev_comment'>"+ comm.val(),然后将其放入您的页面。因此,在这段代码中,您只是直接从输入中获取原始评论值。您没有使用保存到数据库中的编码版本。 -
遗憾的是,教育工作者和教育机构在 IT 主题上极度过时是很常见的,因为 IT 主题每 1-2 年更新和更新一次,而其他教育主题(木工/科学/历史)几十年甚至几个世纪都没有太大的变化,导师们不习惯必须真正探索和重新探索 最佳实践。这样你作为学生就会陷入困境;要么按照你的导师的期望去做,或做最佳实践。这不是一个很好的选择,并导致许多 IT 公司每次都将经验超过成绩。祝你好运
-
将
htmlspecialchars应用于插入数据库的数据,从根本上说是错误的。这应该发生在从数据库中读回数据时,即数据放入 HTML 上下文的那一刻。但是您甚至还没有向我们展示 那个 部分,目前您从服务器返回给客户端的唯一内容是会话中的用户名,所有其他值仍然是客户端的开始。
标签: php html xss websecurity