PHP mysql_real_escape_string()保护数据库名称吗?

Bri*_*ian 4 php mysql sql-injection

我知道mysql_real_escape_string()
会将反斜杠添加到以下字符:\ x00,\n,\ r,\,',"和\ x1a

我知道这是如何保护查询不被注入到where子句中的变量之类的东西.但这是一个我不确定的情景:

$query = "SELECT * FROM $db WHERE 1";

如果从用户输入获取$ db,则用户可以插入如下内容:
$ db = 'RealDatabase WHERE 1; DELETE FROM RealDatabase WHERE 1; SELECT FROM RealDatabase';

根据我的理解,mysql_real_escape_string()不会影响这个字符串,使得最终查询: $query = "SELECT * FROM RealDatabase WHERE 1; DELETE FROM RealDatabase WHERE 1; SELECT FROM RealDatabase WHERE 1";

这会删除数据库.我还没有意识到另一层保护吗?

zom*_*bat 8

您正在寻找的保护级别由反引号提供:

"SELECT * FROM `$db` WHERE 1";
Run Code Online (Sandbox Code Playgroud)

反引号用于限定可能含糊不清的标识符(即MySQL保留字),如果您接受用户输入或具有可变命名的列或数据库,您绝对应该使用反引号,或者我可以保证您会遇到将来的麻烦.例如,如果你有一个系统,其中一个临时字段名称是用一些用户输入创建的,那么只有结果是该字段最终被命名update

"SELECT field1,field2,update FROM table;"
Run Code Online (Sandbox Code Playgroud)

它悲惨地失败了.然而:

"SELECT `field`,`field2`,`update` FROM table"
Run Code Online (Sandbox Code Playgroud)

工作得很好.(这实际上是几年前我曾经处理过这个问题的系统的一个真实例子).

这解决了你输入错误SQL的问题.例如,以下查询将只返回"未知列"错误,其中test; DROP TABLE test是注入的攻击代码:

"SELECT * FROM `test; DROP TABLE test`;"
Run Code Online (Sandbox Code Playgroud)

但要小心:使用反引号仍然可以进行SQL注入!

例如,如果您的$db变量包含其中有反引号的数据,您仍然可以以正常方式注入一些SQL.如果你正在为数据库和字段名称使用可变数据,你应该在将它放入语句之前删除所有反引号,然后在内部使用反引号对其进行限定.

$db = str_replace('`','',$db);
$sql = "SELECT * FROM `$db` WHERE 1";
Run Code Online (Sandbox Code Playgroud)

我利用数据库包装器,它具有单独的功能来清理数据和清理数据库标识符,这就是后者所做的:)