我从不同的博客中发现,强烈建议您使用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);
,但它为我提供了存储在数据库中的相同数据副本。如果我不使用htmlspecialchars()
,只需$post
即可获得预期结果,我认为容易受到XSS Attack
感谢您的时间,并期待从同行那里获得帮助。
修改
我得到了在答案中使用htmlspecialchars_decode()
或html_entity_decode()
的建议,但是
(https://stackoverflow.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
........................
........................
}
答案 0 :(得分:8)
我正在使用
filter_input()
过滤来自用户的任何数据,然后再插入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')
以获得最佳效果。
推荐阅读:Taylor Hornby的Web Application Security。
答案 1 :(得分:0)
我认为您的策略存在问题。
你当然需要过滤输入和输出内容,但是你要覆盖它们 - 双重逃避 问题是你的输入过滤器也在做输出过滤器的工作。
由于我在发送到数据库之前使用了filter_input()来过滤数据,因此可以安全地从数据库直接输出数据($ post = $ posted_data;)而不使用htmlspecialchars吗?
没有。不要相信你的数据库,或者至少不要总是如此。它不会是SQL注入导致巨大XSS的第一种情况。
如果我必须使用htmlspecialchars输出数据,那么在这种情况下我该怎么办呢?
如上所述,停止使用输入过滤器进行输出过滤。您的输入过滤器应确保数据对内部使用是安全的 - 以保护您的应用程序免受非缩进操作。因此,在插入数据库之前,您不需要转义HTML,作为奖励,您可以节省空间。
另一方面,输出过滤器关心最终用户。您从db获取数据并将其发送给用户。我们正在谈论htmlspecialchars
这对ENT_QUOTES
来说没问题,但我认为还不够。您还应该转义(
)
[
]
=
+
-
\
等字符,因为有些情况您不需要成功的XSS攻击来打开/结束任何标记或使用引号。例如,当您将数据输出到onclick
等
我刚看到htmlspecialchars
有double_encode参数,这最终会解决您的问题:
htmlspecialchars($string, ENT_QUOTES, "UTF-8", false);
执行此操作将始终保持HTML特殊字符转义,并且不会逃脱已转义的内容。
答案 2 :(得分:-1)
你想要反过来:) htmlspecialchars_decode()
答案 3 :(得分:-1)
您不需要,当您对它们进行编码并将其保存到数据库时,它们将显示在网页上(当您使用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;
}