$myq = sprintf("select user from table where user='%s'", $_POST["user"]);
I would like to know if the above query can be exploited using SQL injection. Is there any advanced SQL injection technique that could break sprintf
for this particular query?
我想知道是否可以使用SQL注入来利用上述查询。有什么先进的SQL注入技术可以打破sprintf对这个特定查询的限制吗?
8 个解决方案
#1
25
I don't think it needs to be particularly advanced... try an input of
我认为它不需要特别先进……尝试一个输入
' OR 1 = 1 OR user='
In other words, you'll get SQL of:
换句话说,您将得到SQL of:
select user from table where user='' OR 1 = 1 OR user=''
Does that look like a query you really want to execute? (Now consider the possibility of it dropping tables instead, or something similar.)
这看起来像您真正想要执行的查询吗?(现在考虑一下,它可能会掉下桌子,或者类似的东西。)
The bottom line is that you should be using a parameterised query.
底线是您应该使用参数化查询。
#2
8
Yes, I'd say you have a potential problem there :)
是的,我想说你有一个潜在的问题:
You need to escape: \x00, \n, \r, \, ', "
and \x1a
. sprintf() does not do that, sprintf()
does no modification to strings, it just expands whatever variadic arguments that you give it into the buffer that you provide according to the format that you specify.
您需要转义:\x00、\n、\r、\ '和\x1a。sprintf()不会这样做,sprintf()不会对字符串做任何修改,它只是将您根据指定的格式提供的可变参数扩展到您所提供的缓冲区中。
If the strings ARE being transformed, its likely due to magic quotes (as Rob noted in Comments), not sprintf()
. If that is the case, I highly recommend disabling them.
如果字符串正在被转换,它很可能是由于魔术引号(正如Rob在注释中提到的),而不是sprintf()。如果是这样,我强烈建议禁用它们。
#3
8
Using sprintf
doesn’t give you any more protection than using simple string concatenation. The advantage of sprintf
is just having it a little more readable than when to using simple PHP’s string concatenation. But sprintf
doesn’t do any more than simple string concatenation when using the %s
format:
使用sprintf并不比使用简单的字符串连接提供更多的保护。sprintf的优点是,它的可读性比使用简单的PHP字符串连接要高一些。但是sprintf在使用%s格式时只执行简单的字符串连接:
$str = implode('', range("\x00", "\xFF")); // string of characters from 0x00 – 0xFF
var_dump(sprintf("'%s'", $str) === "'".$str."'"); // true
You need to use functions that escape the contextual special characters you want to insert your data into (in this case a string declaration in MySQL, supposing you’re using MySQL) like **mysql_real_escape_string**
does:
您需要使用一些函数来转义要插入数据的上下文特殊字符(在本例中是MySQL中的字符串声明,假设您使用的是MySQL),比如**mysql_real_escape_string*:
$myq = sprintf("select user from table where user='%s'", mysql_real_escape_string($_POST["user"]));
#4
4
when $_POST["user"] would equal "';SHUTDOWN;" - what would happen?
当$_POST["user"]将等于"';SHUTDOWN;"——会发生什么?
#5
1
Actually, turn off magic quotes.
实际上,关掉神奇的引语。
In PHP, where it's appropriate, use filters:
在PHP中,使用过滤器:
$inUser = $_POST['user'];
$outUser = filter_var($inUser, FILTER_SANITIZE_STRING);
Filters strip out HTML tags and escape various characters.
过滤器去掉HTML标签并避开各种字符。
In addition, you can let your database escape it for you:
此外,您还可以让数据库为您转义:
$inUser = $_POST['user'];
$outUser = mysqli_real_escape_string($conn, $inUser);
This escapes MySQL specific special characters like double quotes, single quotes, etc.
它转义MySQL特定的特殊字符,如双引号、单引号等。
Finally, you should use parameterized queries:
最后,您应该使用参数化查询:
$sql = "SELECT user FROM table WHERE user = ?";
$stmt = $pdo->prepare($sql);
$params = array($outUser);
$stmt->execute($params);
Parameterized queries automatically add the quotes around strings, etc., and have further restrictions that make SQL injections even more difficult.
参数化查询会自动在字符串周围添加引号等,并具有进一步的限制,使SQL注入变得更加困难。
I use all three, in that order.
这三个我都用了,按这个顺序。
#6
1
Ahh here I come with the magic answer! :)magic quotes
do escaping for you!
啊,我带来了神奇的答案!(《神奇箴言》为你做的是转义!
So, you have to turn magic_quotes_gpc ini directive off
and then use mysql_real_escape_string as suggested.
因此,您必须关闭magic_quotes_gpc ini指令,然后按照建议使用mysql_real_escape_string。
#7
0
Yes.
是的。
If somebody put in the following as the user in your form:
如果有人在您的表单中以用户的身份输入以下内容:
'; delete * from table
#8
0
$_POST["user"] = "' or 1=1 or user='"
#1
25
I don't think it needs to be particularly advanced... try an input of
我认为它不需要特别先进……尝试一个输入
' OR 1 = 1 OR user='
In other words, you'll get SQL of:
换句话说,您将得到SQL of:
select user from table where user='' OR 1 = 1 OR user=''
Does that look like a query you really want to execute? (Now consider the possibility of it dropping tables instead, or something similar.)
这看起来像您真正想要执行的查询吗?(现在考虑一下,它可能会掉下桌子,或者类似的东西。)
The bottom line is that you should be using a parameterised query.
底线是您应该使用参数化查询。
#2
8
Yes, I'd say you have a potential problem there :)
是的,我想说你有一个潜在的问题:
You need to escape: \x00, \n, \r, \, ', "
and \x1a
. sprintf() does not do that, sprintf()
does no modification to strings, it just expands whatever variadic arguments that you give it into the buffer that you provide according to the format that you specify.
您需要转义:\x00、\n、\r、\ '和\x1a。sprintf()不会这样做,sprintf()不会对字符串做任何修改,它只是将您根据指定的格式提供的可变参数扩展到您所提供的缓冲区中。
If the strings ARE being transformed, its likely due to magic quotes (as Rob noted in Comments), not sprintf()
. If that is the case, I highly recommend disabling them.
如果字符串正在被转换,它很可能是由于魔术引号(正如Rob在注释中提到的),而不是sprintf()。如果是这样,我强烈建议禁用它们。
#3
8
Using sprintf
doesn’t give you any more protection than using simple string concatenation. The advantage of sprintf
is just having it a little more readable than when to using simple PHP’s string concatenation. But sprintf
doesn’t do any more than simple string concatenation when using the %s
format:
使用sprintf并不比使用简单的字符串连接提供更多的保护。sprintf的优点是,它的可读性比使用简单的PHP字符串连接要高一些。但是sprintf在使用%s格式时只执行简单的字符串连接:
$str = implode('', range("\x00", "\xFF")); // string of characters from 0x00 – 0xFF
var_dump(sprintf("'%s'", $str) === "'".$str."'"); // true
You need to use functions that escape the contextual special characters you want to insert your data into (in this case a string declaration in MySQL, supposing you’re using MySQL) like **mysql_real_escape_string**
does:
您需要使用一些函数来转义要插入数据的上下文特殊字符(在本例中是MySQL中的字符串声明,假设您使用的是MySQL),比如**mysql_real_escape_string*:
$myq = sprintf("select user from table where user='%s'", mysql_real_escape_string($_POST["user"]));
#4
4
when $_POST["user"] would equal "';SHUTDOWN;" - what would happen?
当$_POST["user"]将等于"';SHUTDOWN;"——会发生什么?
#5
1
Actually, turn off magic quotes.
实际上,关掉神奇的引语。
In PHP, where it's appropriate, use filters:
在PHP中,使用过滤器:
$inUser = $_POST['user'];
$outUser = filter_var($inUser, FILTER_SANITIZE_STRING);
Filters strip out HTML tags and escape various characters.
过滤器去掉HTML标签并避开各种字符。
In addition, you can let your database escape it for you:
此外,您还可以让数据库为您转义:
$inUser = $_POST['user'];
$outUser = mysqli_real_escape_string($conn, $inUser);
This escapes MySQL specific special characters like double quotes, single quotes, etc.
它转义MySQL特定的特殊字符,如双引号、单引号等。
Finally, you should use parameterized queries:
最后,您应该使用参数化查询:
$sql = "SELECT user FROM table WHERE user = ?";
$stmt = $pdo->prepare($sql);
$params = array($outUser);
$stmt->execute($params);
Parameterized queries automatically add the quotes around strings, etc., and have further restrictions that make SQL injections even more difficult.
参数化查询会自动在字符串周围添加引号等,并具有进一步的限制,使SQL注入变得更加困难。
I use all three, in that order.
这三个我都用了,按这个顺序。
#6
1
Ahh here I come with the magic answer! :)magic quotes
do escaping for you!
啊,我带来了神奇的答案!(《神奇箴言》为你做的是转义!
So, you have to turn magic_quotes_gpc ini directive off
and then use mysql_real_escape_string as suggested.
因此,您必须关闭magic_quotes_gpc ini指令,然后按照建议使用mysql_real_escape_string。
#7
0
Yes.
是的。
If somebody put in the following as the user in your form:
如果有人在您的表单中以用户的身份输入以下内容:
'; delete * from table
#8
0
$_POST["user"] = "' or 1=1 or user='"