Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php mysql_real_escape_string()对十六进制编码的数据不安全吗?_Php_Mysql - Fatal编程技术网

Php mysql_real_escape_string()对十六进制编码的数据不安全吗?

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

我们知道,在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 * 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:如果你有一个你想回答的问题,我建议发布它,这样其他人可能会帮助你。恐怕我对合作不感兴趣继续在这里与你合作。干杯!