PHP SQL 注入失败 [重复]

PHP SQL Injection Failing [duplicate]

提问人:Khaldoun Nd 提问时间:7/26/2021 更新时间:7/26/2021 访问量:99

问:

我是一名编码学校的导师,我正在向我的学生介绍PHP以及PDO和准备好的语句等概念。为了向他们展示准备好的语句(除其他外)如何有助于防止 SQL 注入,我正在尝试以我自己的形式进行一些自己的 SQL 注入。我已经尝试了数十种查询变体,但没有成功,即使当我在 PHPMyAdmin 上运行它们时,这些查询给出了预期的结果。这就引出了一个问题:PHP最近是否引入了一些额外的东西来防止SQL注入?或者也许我做错了什么?DELETE FROM users

以下是我用于插入新用户的代码:

try {
  $sql = "INSERT INTO users (name, email) VALUES ('$name', '$email')";

  $this->conn->exec($sql);
  echo "New record created successfully";
} catch (PDOException $exception) {
  echo $exception;
}

每当我尝试任何输入时,就像它给我的那样Bob'); DELETE FROM users where ('1' = '1

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELETE FROM users where ('1' = '1')' at line 1 

即使相同的查询在 PHPMyAdmin 上有效

有什么想法吗?

php mysql pdo sql 注入

评论

0赞 Definitely not Rafal 7/26/2021
假设:它不起作用,因为您的第一个查询除了 2 个输入......如果你要调试它(例如),你会看到你的查询实际上看起来像这样:,你说你的插入查询插入名称电子邮件,但你只提供了名称=>语法错误。请尝试(--注释掉其余部分。$name == "Bob'); DELETE FROM users where ('1' = '1"echo $sqlINSERT INTO users (name, email) VALUES ('Bob'); ... /* Rest doesnt matter */$name = "someName', 'someEmail'); DELETE FROM users; --"
0赞 Khaldoun Nd 7/26/2021
@DefinitelynotRafal是的,我显示的输入实际上是针对电子邮件的。我正常使用的名字。我也尝试使用,但也没有用。查询直接在分号后中断。我想正如下面的答案所提到的,PDO 不允许我在 ;--
0赞 Definitely not Rafal 7/26/2021
你能提供输出吗?echo $sql

答:

0赞 Bill Karwin 7/26/2021 #1

编辑答案:

如上面的评论中所述,您尝试 SQL 注入实际上是一个错误,因为您没有将两个值传递给 VALUES 子句,即使 INSERT 需要两个值。

默认情况下,PDO实际上支持多查询,但这对于MySQL查询接口来说是不寻常的。MySQL C API 需要特殊的连接选项才能启用多查询,并且大多数连接器不会设置该选项。查看 https://dev.mysql.com/doc/c-api/8.0/en/c-api-multiple-queries.html

这不是PDO是否已经成熟到可以预防它的问题;PDO 通过设计实现多查询。这很不幸,因为它启用了一整类 SQL 注入漏洞,而且没有必要。最好禁用多查询选项,而是一次只运行一个查询。正如MySQL工程部前主管曾经告诉我的那样,“多查询功能没有充分的理由存在。

但是,由于这对于一般的MySQL连接器来说是不寻常的,因此它可能不是SQL注入的一个很好的例子。

尝试使用值“O'Reilly”进行操作。$name

运行以分号分隔的多个语句在大多数查询 API 中不起作用。因此,令人尊敬的 Little Bobby Tables 卡通片在大多数时候都不起作用。

但 SQL 注入可能更微妙。注入的语法可能会导致其他效果,即使它仅限于一个语句。例如,在这种情况下,INSERT 语句可以输入多行。

但大多数情况下,SQL注入不是恶意用户的蓄意攻击。这只是一个语法错误。

$sql = "INSERT INTO users (name, email) VALUES ('O'Reilly', '[email protected]')";
                                                  ^

看到这里的问题了吗?额外的引号将导致此 INSERT 失败。

评论

0赞 Khaldoun Nd 7/26/2021
可悲的是,几年前,当我在一家公司面试时,工程经理发现了一个我错过的表单输入,并使用了经典的表单,破坏了我的 docker 数据库,毁了我的整个应用程序。这就是为什么我试图复制这个特定的场景。但是,是的,我完全同意,如果没有适当的卫生和处理特殊字符,例如“它会抛出错误。另外,正如你所说,我相信PDO现在已经足够成熟,可以防止多次查询。Drop table users
0赞 Bill Karwin 7/26/2021
我投了反对票,这是公平的,因为我犯了一个错误。我为我的答案重写了一个新的介绍。