Php 此查询易受sql注入攻击吗?

Php 此查询易受sql注入攻击吗?,php,sql,sql-injection,Php,Sql,Sql Injection,我想知道是否可以使用SQL注入利用上述查询。是否有任何高级SQL注入技术可以打破此特定查询的sprintf?我认为它不需要特别高级。。。尝试输入 $myq = sprintf("select user from table where user='%s'", $_POST["user"]); 换句话说,您将获得以下SQL值: ' OR 1 = 1 OR user=' 这看起来像是您真正想要执行的查询吗?(现在考虑它可能掉桌子,或者类似的东西。) 底线是您应该使用参数化查询。当$\u POST

我想知道是否可以使用SQL注入利用上述查询。是否有任何高级SQL注入技术可以打破此特定查询的sprintf?

我认为它不需要特别高级。。。尝试输入

$myq = sprintf("select user from table where user='%s'", $_POST["user"]);
换句话说,您将获得以下SQL值:

' OR 1 = 1 OR user='
这看起来像是您真正想要执行的查询吗?(现在考虑它可能掉桌子,或者类似的东西。)


底线是您应该使用参数化查询。

当$\u POST[“user”]等于“;SHUTDOWN;”-会发生什么情况?

是的

select user from table where user='' OR 1 = 1 OR user=''
如果有人在您的表单中输入以下内容作为用户:

$_POST["user"] = "' or 1=1 or user='"
使用不会比使用简单的字符串串联提供更多的保护。
sprintf
的优点是它比使用简单的PHP字符串连接时可读性更强。但是
sprintf
在使用
%s
格式时只执行简单的字符串连接:

'; delete * from table
您需要使用转义要插入数据的上下文特殊字符的函数(在本例中,假设您使用的是MySQL),如下所示:


是的,我想说你有一个潜在的问题:)

您:
\x00、\n、\r、\、'、“
\x1a
sprintf()
不修改字符串,它只是根据指定的格式将您赋予它的任何可变参数扩展到您提供的缓冲区中


如果字符串正在被转换,很可能是由于(如注释中所述),而不是由于
sprintf()
。如果是这样,我强烈建议禁用它们。

啊,我给出了神奇的答案!:)
magic quotes
帮你逃命吧

因此,您必须关闭magic\u quotes\u gpc ini指令

然后按照建议使用mysql\u real\u escape\u字符串。

实际上,请关闭magic quotes

在PHP中,如果合适,请使用过滤器:

$myq = sprintf("select user from table where user='%s'", mysql_real_escape_string($_POST["user"]));
过滤器去除HTML标记并转义各种字符

此外,您还可以让数据库为您转义:

$inUser = $_POST['user'];
$outUser = filter_var($inUser, FILTER_SANITIZE_STRING);
这将转义MySQL特定的特殊字符,如双引号、单引号等

最后,您应该使用参数化查询:

$inUser = $_POST['user'];
$outUser = mysqli_real_escape_string($conn, $inUser);
参数化查询会自动在字符串等周围添加引号,并具有进一步的限制,使得SQL注入更加困难


我按顺序使用这三种方法。

sprintf将转义单引号,发送到db的查询将是select user from table,其中user='\';SHUTDOWN;'如果海报不使用mysqli\u multi\u查询,什么也不会发生,因为PHP中的所有其他mysql查询方法只执行一个查询。不,它不会。至少在我与PH的经验中不会P.@user294924,%s告诉printf子系统打印变量参数包含的任何字符串。它不进行检查、过滤、转义。它完全按照您的指示执行。@schraspel上校:困扰我们大多数人的不是否决票,而是有人点击按钮说“答案不好”“没有提供关于它如何可能是错误的或如何更好地表达它的建议。如果一条评论被留作任何形式的投票,它对每个人都有帮助,因为它帮助人们学习并写出更好的答案。“权威”徽章的存在是为了鼓励人们留下信息丰富的评论。@Sprapnel上校:我认为这与-2的声誉无关。而是得到一个关于答案有什么问题的回答来改进它。“底线是你应该使用一个参数化的查询。”100%同意。SQL注入并不是唯一的原因。至少在Oracle中,出于性能原因,您应该尽可能绑定变量。这样DB就可以重用以前解析过的查询和计算过的执行计划,并跳过执行计划计算过程中必需的锁定。你反对使用mysql\u real\u escape\u string有什么原因吗?不知道你从哪里得到的,但是sprintf什么也没有逃逸。实际上,这是查找sql注入任务的一部分。我在本地复制了这个场景,并尝试了所有正常的sql注入$a=sprintf(“从表中选择用户,其中用户='%s',$\u POST[“user”]);echo$a我一直在得到用\转义的引号。中间是否有可能漏掉引号?你可能启用了魔法引号。@罗布——这真的很有帮助。谢谢你,虽然它不能与普通的mysql一起工作,但它很好。例如,用什么更好的方法来过滤不需要的帖子或获取“mysqli\u real\u escape\u string”或“filter\u SANITIZE\u string”?-1因为:他需要更多的转义,而且,如果他在任何查询中忘记做一个,他就被解雇了。一句话:最好有一个非常好的、特定的理由从连接的字符串构建查询字符串,否则,请始终使用参数化查询。@BryanH另外两个人告诉他,他需要使用参数化查询。我特别回答了
sprintf()
,因为OP很难理解为什么它没有做他认为它在做的事情(参见Jon回答下面的评论)。我没有建议他只使用连接字符串:)
$inUser = $_POST['user'];
$outUser = mysqli_real_escape_string($conn, $inUser);
$sql = "SELECT user FROM table WHERE user = ?";
$stmt = $pdo->prepare($sql);
$params = array($outUser);
$stmt->execute($params);