Php mysql_real_escape_string()对十六进制编码的数据不安全吗?
我们知道,在php脚本中对mysql执行之前,所有用户输入都必须通过Php mysql_real_escape_string()对十六进制编码的数据不安全吗?,php,mysql,Php,Mysql,我们知道,在php脚本中对mysql执行之前,所有用户输入都必须通过mysql\u real\u escape\u string()函数进行转义。并知道此函数在用户输入的任何“或”字符之前插入\。假设以下代码: $_POST['username'] = 'aidan'; $_POST['password'] = "' OR ''='"; // Query database to check if there are any matching users $query = "SELECT * F
mysql\u real\u escape\u string()
函数进行转义。并知道此函数在用户输入的任何“
或”
字符之前插入\。假设以下代码:
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";
// Query database to check if there are any matching users
$query = "SELECT * FROM users WHERE user='".mysql_real_escape_string($_POST['username']."' AND password='".mysql_real_escape_string($_POST['password']."'";
mysql_query($query);
// This means the query sent to MySQL would be:
echo $query;
这个密码是安全的
但我发现,如果用户以十六进制格式输入输入,那么mysql\u real\u escape\u string()
就不能做任何事情,用户可以轻松地执行sql注入。在下面的27204f52027273d27
中,是相同的”或“=”
但采用十六进制格式,sql执行没有问题:
$_POST['username'] = 'aidan';
$_POST['password'] = "27204f522027273d27";
// Query database to check if there are any matching users
$query = "SELECT * FROM users WHERE user='".mysql_real_escape_string($_POST['username']."' AND password='".mysql_real_escape_string($_POST['password']."'";
mysql_query($query);
// This means the query sent to MySQL would be:
echo $query;
但这是否是真的,如果答案是肯定的,我们如何才能以这种方式防止sql注入?如果您正在使用,那么使用预先准备好的语句可能会更好
对于您的特定情况,请尝试以下代码:
/*
Somewhere earlier in your application, you will have to set $dbh
by connecting to your database using code like:
$dbh = new PDO('mysql:host=localhost;dbname=test', $DBuser, $DBpass);
*/
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";
$user = $_POST['username'];
$password = $_POST['password'];
// Query database to check if there are any matching users
$query = "SELECT * FROM users WHERE user=? AND password=?";
$stmt = $dbh->prepare($query);
$stmt->bindParam(1, $user);
$stmt->bindParam(2, $password);
$stmt->execute();
这确实需要在数据库交互中使用PDO,但总的来说这是件好事
另请参阅和已接受的答案,我从中获得了一些答案。在处理漏洞等问题时,最好提供一个代码示例(必要时进行简化以演示问题)以及触发您看到的问题的输入。请演示攻击者如何使用十六进制表示法绕过
mysql\u real\u escape\u string
。@deceze:一个如何使用十六进制编码绕过转义的示例。@Ahmad:通过编辑,问题有了很大的改进!谢谢!我将更新我的回答。@Ahmad您给出的示例没有显示任何问题,运行该查询按预期工作。这并不能真正回答问题。是的,准备好的语句更可取,但问题有所不同。此外,如果数据库不支持pre-code,PDO将返回到类似于mysql\u real\u escape\u string
的行为deceze:恐怕这是不准确的。正如我在聊天中详细介绍的,这解决了可能的攻击向量。此外,过去十年中发布的任何MySQL版本都支持PDOs。现在回到MySQL_real_escape_string()
永远不会现实发生。我不认为这种方式的好斗对提问者有帮助。我也不认为回避核心问题有帮助。详情见::)@deceze:如果你有一个你想回答的问题,我建议发布它,这样其他人可能会帮助你。恐怕我对合作不感兴趣继续在这里与你合作。干杯!