当查询中的变量没有引号时,mysql_real_escape_string的SQL注入是否可能?

时间:2021-01-15 22:32:28

Take for example this

以这个为例

$username = mysql_real_escape_string($_GET['username']);
$password = mysql_real_escape_string($_GET['password']);
$sql = "SELECT * FROM users WHERE username = $username AND password = $password";

If there are no quotes around $username and $password, is injection still possible ?

如果$username和$password附近没有引号,是否仍然可以进行注入?

3 个解决方案

#1


3  

If there are no quotes around $username and $password, is injection still possible ?

如果$username和$password附近没有引号,是否仍然可以进行注入?

Yes. mysql_real_escape_string() prevents only escaping from the quotes in a string.

是的。mysql_real_escape_string()防止仅从字符串中的引号转义。

Without surrounding quotes, mysql_real_escape_string() is useless.

如果没有引号,mysql_real_escape_string()就没有用了。

#2


1  

Yes. Trivially, submit the username as username and the password as password. Congratulations, you're in. That's because this expands to:

是的。通常情况下,提交用户名作为用户名,密码作为密码。祝贺你,你在。这是因为它扩展为:

$sql = "SELECT * FROM users WHERE username = username AND password = password";

It will select any row where the username column equals the username column (same for password).

它将选择用户名列等于用户名列的任何行(密码相同)。

Of course, this code also fails for ordinary logins, so it should be caught pretty quickly. If you use any username or password that is not a database construct (column, function call, etc.), it will fail.

当然,这段代码也不能用于普通的登录,所以应该很快就会被发现。如果您使用的用户名或密码不是数据库结构(列、函数调用等),那么它将失败。

#3


0  

Without the quotes, the user-submitted data will be seen as field references, and/or invalid SQL.

如果没有引号,用户提交的数据将被视为字段引用和/或无效的SQL。

Consider a username of username. A proper query would be:

考虑用户名的用户名。适当的查询是:

SELECT ... FROM ... WHERE username='username'

and only match if there really is a user whose name is "username".

只有当用户的名字是“用户名”时才匹配。

Without the quotes, it becomes:

没有引号,它变成:

SELECT ... FROM ... WHERE username=username

which would match ALL non-null records in the table.

它将匹配表中的所有非空记录。

Now consider a 2-part username: John doe

现在考虑一个两部分的用户名:John doe

SELECT ... FROM ... WHERE username=John doe

The DB server will try to compare the username field against a field name 'John', which most likely doesn't exist. Then there's this "doe" thing in there which is not a field name, not an SQL key word, so is a syntax error.

DB服务器将尝试将用户名字段与字段名“John”进行比较,后者很可能不存在。这里有个"doe"不是字段名,不是SQL关键字,语法错误也是。

Now consider a username: 1 or 1=1

现在考虑用户名:1或1=1

SELECT ... FROM ... WHERE username=1 or 1=1

again, this will ALWAYS return true and match ALL rows, because "1=1" will always be true.

同样,它总是返回true并匹配所有的行,因为“1=1”总是为true。

mysql_real_escape_string() only guarantees that any data you pass through it will not "break" a PROPERLY CONSTRUCTED query. If the query you're inserting the escaped data into is NOT properly constructed, then all bets are off.

mysql_real_escape_string()仅保证传递给它的任何数据不会“中断”正确构造的查询。如果您要插入转义数据的查询没有正确构造,那么所有的赌注都是无效的。

#1


3  

If there are no quotes around $username and $password, is injection still possible ?

如果$username和$password附近没有引号,是否仍然可以进行注入?

Yes. mysql_real_escape_string() prevents only escaping from the quotes in a string.

是的。mysql_real_escape_string()防止仅从字符串中的引号转义。

Without surrounding quotes, mysql_real_escape_string() is useless.

如果没有引号,mysql_real_escape_string()就没有用了。

#2


1  

Yes. Trivially, submit the username as username and the password as password. Congratulations, you're in. That's because this expands to:

是的。通常情况下,提交用户名作为用户名,密码作为密码。祝贺你,你在。这是因为它扩展为:

$sql = "SELECT * FROM users WHERE username = username AND password = password";

It will select any row where the username column equals the username column (same for password).

它将选择用户名列等于用户名列的任何行(密码相同)。

Of course, this code also fails for ordinary logins, so it should be caught pretty quickly. If you use any username or password that is not a database construct (column, function call, etc.), it will fail.

当然,这段代码也不能用于普通的登录,所以应该很快就会被发现。如果您使用的用户名或密码不是数据库结构(列、函数调用等),那么它将失败。

#3


0  

Without the quotes, the user-submitted data will be seen as field references, and/or invalid SQL.

如果没有引号,用户提交的数据将被视为字段引用和/或无效的SQL。

Consider a username of username. A proper query would be:

考虑用户名的用户名。适当的查询是:

SELECT ... FROM ... WHERE username='username'

and only match if there really is a user whose name is "username".

只有当用户的名字是“用户名”时才匹配。

Without the quotes, it becomes:

没有引号,它变成:

SELECT ... FROM ... WHERE username=username

which would match ALL non-null records in the table.

它将匹配表中的所有非空记录。

Now consider a 2-part username: John doe

现在考虑一个两部分的用户名:John doe

SELECT ... FROM ... WHERE username=John doe

The DB server will try to compare the username field against a field name 'John', which most likely doesn't exist. Then there's this "doe" thing in there which is not a field name, not an SQL key word, so is a syntax error.

DB服务器将尝试将用户名字段与字段名“John”进行比较,后者很可能不存在。这里有个"doe"不是字段名,不是SQL关键字,语法错误也是。

Now consider a username: 1 or 1=1

现在考虑用户名:1或1=1

SELECT ... FROM ... WHERE username=1 or 1=1

again, this will ALWAYS return true and match ALL rows, because "1=1" will always be true.

同样,它总是返回true并匹配所有的行,因为“1=1”总是为true。

mysql_real_escape_string() only guarantees that any data you pass through it will not "break" a PROPERLY CONSTRUCTED query. If the query you're inserting the escaped data into is NOT properly constructed, then all bets are off.

mysql_real_escape_string()仅保证传递给它的任何数据不会“中断”正确构造的查询。如果您要插入转义数据的查询没有正确构造,那么所有的赌注都是无效的。