php - php函数htmlspecialchars不起作用
问题描述
在我必须为学校做的一个项目中,需要在我的网站上防止 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);
}
}
解决方案
对于您提出的问题以及您的代码中显而易见的问题,我将在这里列出一些有用的答案:
1)
如何正确设置您的 PDO 连接——一个很好的设置使用指南。
如何使用 PDO 准备语句- 准备语句从根本上比以前插入数据的方法更安全。你正在使用 PDO,但你没有准备你的陈述,所以你快到了....
2)
注意:您应该htmlspecialchars
在输出数据时使用,而不是在将数据输入数据库时使用。
3)
如果您想在源输入中允许任何HTML,那么您应该在表单数据上使用HTML Purifier,一旦将其发送回您的服务器并在插入数据库之前。
4)
有很多 MySQL最佳实践可供查找和使用,我找不到一篇好的文章来解释这一切,但我真正需要向您概述的是
您不应该使用root
登录来通过网站访问/保存数据。始终使用另一个自定义用户,该用户仅具有所需的有限权限。
(如果有人有指向 4 的 URL 参考的链接,那就太好了!)
祝你好运
是的,但是在 php 或 jquery 中?我知道这是一个 php 函数,所以我在考虑我的 php 代码的第一部分。如果你也可以写我必须插入的行,那将非常有用
你的流程应该大致是:
保存数据
- HTML: 通过 HTML(等)收集数据
<form>
,数据通过表单提交发送到服务器。 - PHP根据需要对数据进行可选处理(检查有效性等)
- PHP根据需要使用 HTMLPurifier 或类似工具来安全地删除不需要的 HTML。
- PHP这个收集到的数据应该放到一个
PDO Prepared Statement
- SQL数据被保存到数据库中。
输出数据
- PHP为您想要的数据构建 SQL 请求,通常带有
id
引用调用。 - PHP加载要返回给客户端(用户浏览器)的数据
- PHP在此数据上运行
htmlspecialchars
以禁用 HTML 元素 - HTML数据显示给客户端浏览器。
我理解了这个过程,我也读过那个线程,但我不知道如何在我的代码中编写它
这是您的代码中的一个示例:
还值得注意的是,您应该始终手动引用所有列名,而不是 SELECT * FROM
在 SQL 查询中。
$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);
}
您还应该习惯使用绝对比较运算符===
而不是模糊比较运算符==
。
推荐阅读
- javascript - 自动生成下拉选项
- angular - ChartJs - 禁用动画
- angular - angular 2+ - 在多个焦点输入元素上设置类或样式
- c# - 在阅读或循环期间等待按钮单击
- stackdriver - Stackdriver 日志记录未显示在 GKE 中
- javascript - Django 依赖/链式下拉表单
- bash - 按行号交叉引用两个文件中的字符串并将它们收集到第三个文件中
- node.js - Npm 使用 Homebrew 升级到最新版本
- python - 具有自定义模型的分叉 django-oscar 应用程序无法迁移
- javascript - 从数组中删除项目时,管道不会更新模板