使用已使用 filter_input() 过滤的 htmlspecialchars() 从数据库输出数据
output data from database using htmlspecialchars() that has been filtered using filter_input()
我从不同的博客中发现,强烈建议使用 htmlspecialchars()
在屏幕上输出任何数据以免受 XSS Attack
的影响。
我正在使用 filter_input()
在插入 database
之前过滤来自用户的任何数据。 filter_input()
将 '
等特殊字符转换为 '
并以这种方式保存,例如
I'm going to shopping with Molly's sister;Dolly
。我的问题是
How can I print(output) apostrope or quotes and specific special characters to users screen using htmlspecialchars so that the output would be user friendly
我曾尝试使用 htmlspecialchars($post,ENT_NOQUOTES);
,但它给了我存储在 database.If 中的相同数据副本 我不使用 htmlspecialchars()
,只是 $post
给了我预期的结果,我认为它容易受到 XSS Attack
感谢您的宝贵时间,期待得到同行的帮助。
编辑
我得到了使用 htmlspecialchars_decode()
或 html_entity_decode()
作为答案的建议,但是
(https://whosebug.com/users/1338292/ja͢ck)
和其他一些人建议不要使用这些 functions
在屏幕上输出数据。
请注意,我正在使用 prepared statement
和 parameterized query
。但我不想保留任何安全漏洞,这就是为什么在发送到数据库之前过滤数据。
因为我在发送到数据库之前使用了filter_input()
来过滤数据,所以直接从数据库输出数据($post=$posted_data;
)而不使用htmlspecialchars
是否安全?
如果一定要用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
........................
........................
}
你想反过来:) htmlspecialchars_decode()
您不需要,当您对它们进行编码并将它们保存到数据库时,它们将按原样显示在网页上(当您使用 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;
}
I am using filter_input()
to filter any data that comes from user before inserting into database
.
这是一种不好的做法。 在将数据插入数据库之前不要破坏它。现在是 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']
]);
准备好的语句不再需要 filter_input()
。这样做并没有增加纵深防御,只会破坏数据完整性并让自己头疼。
渲染输出时,如果要允许 HTML,请使用 HTML Purifier。
否则,使用 htmlspecialchars($output, ENT_QUOTES | ENT_HTML5, 'UTF-8')
以获得最佳效果。
推荐阅读:Web Application Security 作者:Taylor Hornby。
我认为你的策略有问题。
您当然需要过滤输入和输出内容,但您正在覆盖它们 - 双重转义。
问题是你的输入过滤器也在做输出过滤器的工作。
As I have used filter_input() to filter data before sending to database,is it safe to output data directly($post=$posted_data;) from database without using htmlspecialchars?
没有。不要相信您的数据库,或者至少不总是如此。这不是第一个 SQL 注入导致巨大 XSS 的案例。
If I must need to use htmlspecialchars to output data,then how can I do it in this case?
正如我上面所说,停止使用输入过滤器进行输出过滤。您的输入过滤器应该确保数据对于内部使用是安全的——以保护您的应用程序免受非缩进操作的影响。因此,您无需在插入到数据库之前转义 HTML,作为奖励,您将节省 space.
另一方面,输出过滤器关心最终用户。您从数据库中获取数据并将其发送给用户。我们谈论的是 htmlspecialchars
,这与 ENT_QUOTES
没问题,但在我看来还不够。你还应该转义像 (
)
[
]
=
+
-
\
这样的字符,因为有一些情况您不需要对 open/end 任何标签或使用引号进行成功的 XSS 攻击。例如当你将数据输出到 onclick
等
我刚刚看到 htmlspecialchars
有 double_encode 参数,这最终会解决你的问题:
htmlspecialchars($string, ENT_QUOTES, "UTF-8", false);
这样做将始终保持 HTML 特殊字符转义,并且不会转义已经转义的内容。
我从不同的博客中发现,强烈建议使用 htmlspecialchars()
在屏幕上输出任何数据以免受 XSS Attack
的影响。
我正在使用 filter_input()
在插入 database
之前过滤来自用户的任何数据。 filter_input()
将 '
等特殊字符转换为 '
并以这种方式保存,例如
I'm going to shopping with Molly's sister;Dolly
。我的问题是
How can I print(output) apostrope or quotes and specific special characters to users screen using htmlspecialchars so that the output would be user friendly
我曾尝试使用 htmlspecialchars($post,ENT_NOQUOTES);
,但它给了我存储在 database.If 中的相同数据副本 我不使用 htmlspecialchars()
,只是 $post
给了我预期的结果,我认为它容易受到 XSS Attack
感谢您的宝贵时间,期待得到同行的帮助。
编辑
我得到了使用 htmlspecialchars_decode()
或 html_entity_decode()
作为答案的建议,但是
(https://whosebug.com/users/1338292/ja͢ck)
和其他一些人建议不要使用这些 functions
在屏幕上输出数据。
请注意,我正在使用 prepared statement
和 parameterized query
。但我不想保留任何安全漏洞,这就是为什么在发送到数据库之前过滤数据。
因为我在发送到数据库之前使用了filter_input()
来过滤数据,所以直接从数据库输出数据($post=$posted_data;
)而不使用htmlspecialchars
是否安全?
如果一定要用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
........................
........................
}
你想反过来:) htmlspecialchars_decode()
您不需要,当您对它们进行编码并将它们保存到数据库时,它们将按原样显示在网页上(当您使用 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;
}
I am using
filter_input()
to filter any data that comes from user before inserting intodatabase
.
这是一种不好的做法。 在将数据插入数据库之前不要破坏它。现在是 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']
]);
准备好的语句不再需要 filter_input()
。这样做并没有增加纵深防御,只会破坏数据完整性并让自己头疼。
渲染输出时,如果要允许 HTML,请使用 HTML Purifier。
否则,使用 htmlspecialchars($output, ENT_QUOTES | ENT_HTML5, 'UTF-8')
以获得最佳效果。
推荐阅读:Web Application Security 作者:Taylor Hornby。
我认为你的策略有问题。
您当然需要过滤输入和输出内容,但您正在覆盖它们 - 双重转义。
问题是你的输入过滤器也在做输出过滤器的工作。
As I have used filter_input() to filter data before sending to database,is it safe to output data directly($post=$posted_data;) from database without using htmlspecialchars?
没有。不要相信您的数据库,或者至少不总是如此。这不是第一个 SQL 注入导致巨大 XSS 的案例。
If I must need to use htmlspecialchars to output data,then how can I do it in this case?
正如我上面所说,停止使用输入过滤器进行输出过滤。您的输入过滤器应该确保数据对于内部使用是安全的——以保护您的应用程序免受非缩进操作的影响。因此,您无需在插入到数据库之前转义 HTML,作为奖励,您将节省 space.
另一方面,输出过滤器关心最终用户。您从数据库中获取数据并将其发送给用户。我们谈论的是 htmlspecialchars
,这与 ENT_QUOTES
没问题,但在我看来还不够。你还应该转义像 (
)
[
]
=
+
-
\
这样的字符,因为有一些情况您不需要对 open/end 任何标签或使用引号进行成功的 XSS 攻击。例如当你将数据输出到 onclick
等
我刚刚看到 htmlspecialchars
有 double_encode 参数,这最终会解决你的问题:
htmlspecialchars($string, ENT_QUOTES, "UTF-8", false);
这样做将始终保持 HTML 特殊字符转义,并且不会转义已经转义的内容。