问题描述
在我必须上学的一个项目中,需要防止在我的网站上进行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","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","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);
}
}
解决方法
在这里,我将针对您所提出的问题以及代码中明显的问题列出一些有用的答案:
1)
How to correctly set up your PDO connection-很好的设置指南。
How to use PDO prepared statements-预备语句从根本上比以前的插入数据方法更安全。您正在使用PDO,但没有准备您的陈述,因此您快要准备好了....
2)
注意:在输出数据时,应使用htmlspecialchars
,而不是将数据输入数据库时使用root
。
3)
如果要在源输入中允许任何 HTML,则应在表单数据上使用HTML Purifier,将其发送回服务器后再插入数据库。
4)
有很多要找到和使用的MySQL 最佳实践,我找不到一篇很好的文章来解释这一切,但是我真的很需要 为您概述
您永远不应使用<form>
登录名通过网站访问/保存数据。总是使用另一个仅具有所需有限权限的自定义用户。
(如果某人有指向4的URL引用的链接,那就太好了!)
祝你好运
是的,但是在php或jquery中?我知道这是一个php函数,所以我正在考虑我的php代码的第一部分。如果您还可以编写该行,则必须插入它,这将非常有用
您的过程应大致为:
保存数据
- HTML::通过HTML
PDO Prepared Statement
(等等)收集数据,数据通过表单提交发送到服务器。 - PHP 根据需要对数据进行可选处理(检查有效性等)
- PHP ,根据需要使用HTMLPurifier或类似工具来安全删除不需要的HTML。
- PHP 该收集的数据应放入
id
- SQL 数据已保存到数据库中。
输出数据
- PHP ,通常使用
htmlspecialchars
参考调用来构建所需数据的SQL请求。 - PHP 将打算返回的数据加载到 Client (用户的浏览器)
- PHP 在此数据上运行
SELECT * FROM
以禁用HTML元素 - HTML 数据显示在客户端浏览器中。
我了解该过程,并且也阅读了该线程,但是我不知道如何在我的代码中编写
这是您代码中的一个示例:
还值得注意的是,您应该始终在SQL查询中手动引用所有列名和 NOT $rows = $db->prepare("SELECT id,name,htmlcode FROM reviews WHERE titolo=:title ORDER BY ora ASC");
$rows->execute(['title' => $ti]); //SAFE SQL query.
if((int)$rows->rowCount() === 0){
echo 0;
} else{
$res = $rows->fetchALL(PDO::FETCH_ASSOC);
// Res will be a multilevel array so you need to apply changes to each subarray key.
foreach($res as &$resRow){
//disable HTML. For example only this is saved into a new array value.
$resRow['commento'] = htmlspecialchars($resRow['commento'],ENT_QUOTES,'UTF-8');
}
echo json_encode($res);
}
。
===
您还应该习惯于使用绝对比较运算符==
而不是模糊的比较运算符{{1}}。