Php 使用已使用filter_input()筛选的htmlspecialchars()从数据库输出数据
我从不同的博客中发现,强烈建议使用Php 使用已使用filter_input()筛选的htmlspecialchars()从数据库输出数据,php,security,mysqli,xss,htmlspecialchars,Php,Security,Mysqli,Xss,Htmlspecialchars,我从不同的博客中发现,强烈建议使用htmlspecialchars()在屏幕上输出任何数据,以防止XSS攻击 我正在使用filter\u input()filter_input()将像'这样的特殊字符转换为'并以这种方式保存,如 I'm going to shopping with Molly's sister;Dolly 1.我的问题是 如何使用htmlspecialchars向用户屏幕打印(输出)撇号或引号以及特定的特殊字符,以使输出对用户友好 我尝
htmlspecialchars()
在屏幕上输出任何数据,以防止XSS攻击
我正在使用filter\u input()filter_input()
将像'
这样的特殊字符转换为'代码>并以这种方式保存,如
I'm going to shopping with Molly's sister;Dolly
1.我的问题是
如何使用htmlspecialchars向用户屏幕打印(输出)撇号或引号以及特定的特殊字符,以使输出对用户友好
我尝试过使用htmlspecialchars($post,entnoquotes)
,但它提供了存储在数据库中的相同数据副本。如果我不使用htmlspecialchars()
,只需$post
就可以得到预期的结果,我认为这很容易受到XSS攻击
感谢您的时间,并期待得到同行的帮助
编辑
我得到建议在回答时使用htmlspecialchars\u decode()
或html\u entity\u decode()
,但是
()
还有一些人建议不要使用这些函数
在屏幕上输出数据
请注意,我正在使用准备语句
和参数化查询
。但我不想保留任何安全漏洞,这就是为什么在发送到数据库之前过滤数据
由于我使用了filter\u input()
在发送到数据库之前过滤数据,所以不使用htmlspecialchars
直接从数据库输出数据($post=$posted\u data;
)安全吗
如果我必须使用htmlspecialchars
来输出数据,那么在这种情况下我该怎么做呢
代码示例
$stmt1=mysqli_stmt_init($connect_dude);
/*Inserting into database*/
if(isset($_POST['titlex']) && isset($_POST['pricex']) && isset($_POST['detailx'])){
$tit=filter_input(INPUT_POST,'titlex',FILTER_SANITIZE_STRING);
$pri=preg_replace('#[^0-9]#','',$_POST['pricex']);
$det=filter_input(INPUT_POST,'detailx',FILTER_SANITIZE_STRING);
$query2="INSERT INTO `hotel1`.`dine` (user_id,title,price,detail) VALUES (?,?,?,?)";
mysqli_stmt_prepare($stmt1,$query2);
mysqli_stmt_bind_param($stmt1, "isis", $logged_id, $tit, $pri, $det);
mysqli_stmt_execute($stmt1);
}
/*Get Data from DB*/
$query1="SELECT id101,title,price,detail FROM `hotel1`.`dine` WHERE user_id=?";
mysqli_stmt_prepare($stmt1,$query1);
mysqli_stmt_bind_param($stmt1, "i", $user_idx);
mysqli_stmt_execute($stmt1);
mysqli_stmt_store_result($stmt1);
mysqli_stmt_bind_result($stmt1, $id101, $title,$price, $detail);
while(mysqli_stmt_fetch($stmt1)){
$id101=$id101;
$title=$title; //htmlspecialchars needed
$price=$price; //htmlspecialchars needed
$detail=$detail; //htmlspecialchars needed
........................
........................
}
您想换一种方式:)您不需要这样做,当您编码它们并将它们保存到DB时,它们将以应有的方式显示在网页上(当您使用echo$result['message'];)。浏览器会自动解码它们
我正在使用此功能剥离输入:
function stripinput($text) {
if (!is_array($text)) {
$text = trim($text);
$text = preg_replace("/(&)+(?=\#([0-9]{2,3});)/i", "&", $text);
$search = array("&", "\"", "'", "\\", '\"', "\'", "<", ">", " ");
$replace = array("&", """, "'", "\", """, "'", "<", ">", " ");
$text = str_replace($search, $replace, $text);
}else{
foreach ($text as $key => $value) {
$text[$key] = stripinput($value);
}
}
return $text;
}
函数条带输入($text){
如果(!is_数组($text)){
$text=修剪($text);
$text=preg_replace(“/(&;)+(?=\#([0-9]{2,3}))/i“,”&“,$text);
$search=array(“&”、“\”、“'”、“\ \”、“\”、“\”、“\”、“\”、“,”);
$replace=数组(“&;”,“&;39;”,“&;92;”,“,”,“&;39;”,“,”,”);
$text=str_replace($search,$replace,$text);
}否则{
foreach($key=>$value的文本){
$text[$key]=stripinput($value);
}
}
返回$text;
}
我正在使用filter\u input()
这是一种不好的做法。在将数据插入数据库之前,不要损坏数据。2015年;不要消毒,而是使用准备好的语句
$db = new \PDO(
'mysql:host=localhost;dbname=mydatabase;charset=UTF-8',
$username,
$password
);
// other stuff in between
$statement = $db->prepare(
"INSERT INTO yourtable (email, username) VALUES (:email, :username);"
);
$success = $statement->execute([
':email' => $_POST['email'],
':username' => $_POST['username']
]);
准备好的语句不再需要过滤输入()。这样做并没有增加深度防御,只会破坏数据完整性,让自己头疼
呈现输出时,如果希望允许HTML,请使用
否则,使用htmlspecialchars($output,ENT_QUOTES | ENT_HTML5,'UTF-8')
获得最佳结果
推荐阅读:泰勒·霍恩比。我认为你的策略有问题
您当然需要过滤输入和输出内容,但您正在覆盖它们-双重转义。
问题是你的输入过滤器也在做输出过滤器的工作
由于我使用filter_input()在发送到数据库之前过滤数据,所以不使用htmlspecialchars直接从数据库输出数据($post=$posted_data;)安全吗
不,不要相信你的数据库,或者至少不总是这样。这不是第一个SQL注入导致巨大XSS的案例
如果我必须使用htmlspecialchars来输出数据,那么在这种情况下我该怎么做呢
如上所述,停止使用输入过滤器进行输出过滤。您的输入过滤器应该确保数据在内部使用时是安全的,以保护您的应用程序不受非缩进操作的影响。因此,在插入到数据库之前,您不需要转义HTML,而且还可以节省空间
另一方面,输出过滤器关心最终用户。您从数据库获取数据并将其发送给用户。我们谈论的是htmlspecialchars
,这对ENT\u引号很好,但在我看来还不够。您还应该转义(
)
[
]
=
+
-
\
),因为有些情况下,成功的XSS攻击不需要打开/结束任何标记或使用引号。例如,当您将数据输出到onclick
,等等
我刚刚看到htmlspecialchars
有双_编码参数,这将最终解决您的问题:
htmlspecialchars($string, ENT_QUOTES, "UTF-8", false);
这样做将始终保持HTML特殊字符的转义,而不会转义已转义的内容。但我被告知htmlspecialchars_decode
输出数据是个坏主意。XSS
riskAh,我现在明白了,我道歉。这是“不那么糟糕”的,如果你想自己处理它,让它更加“安全”,你可以扫描mysql中的文本,并检查它——我不知道使用普通的html_entity_decode()是否安全不过,我没有查看底层的C代码。我已经在使用prepared语句
和参数化查询
。但我不想保留任何安全漏洞,这就是为什么在将数据发送到数据库之前过滤数据。而且,HTMLPurifier
应用于textarea
中我希望允许有限的HTML标记的位置。我将HTMLPurifier
用于textarea,但不用于文本字段。