当前位置: 首页 > 面试题库 >

准备好的语句如何防止SQL注入攻击?

羊舌航
2023-03-14
问题内容

准备好的语句如何帮助我们防止SQL注入攻击?

维基百科说:

准备好的语句可以抵御SQL注入,因为稍后需要使用其他协议传输的参数值不需要正确地转义。如果原始语句模板不是从外部输入派生的,则不会发生SQL注入。

我不太清楚原因。用简单的英语和一些例子,简单的解释是什么?


问题答案:

这个想法很简单-查询和数据被发送到数据库服务器 分开
就这样。

SQL注入问题的根源在于 代码和数据混合。

实际上,我们的SQL查询是 合法程序 。我们正在动态创建这样的程序,动态添加一些数据。因此,数据可能会干扰 程序代码
,甚至对其进行更改,正如每个SQL注入示例所显示的那样(PHP / Mysql中的所有示例):

$expected_data = 1;
$query = "SELECT * FROM users where id=$expected_data";

会产生一个常规查询

SELECT * FROM users where id=1

而这段代码

$spoiled_data = "1; DROP TABLE users;"
$query        = "SELECT * FROM users where id=$spoiled_data";

会产生恶意序列

SELECT * FROM users where id=1; DROP TABLE users;

之所以起作用,是因为我们将数据直接添加到程序主体中,并且它成为程序的一部分,因此数据可能会更改程序,并且根据传递的数据,我们将有常规输出或users删除表。

尽管 在准备语句的情况下我们不会更改程序,但程序仍然保持原样。
这就是重点。

我们先将 程序 发送到服务器

$db->prepare("SELECT * FROM users where id=?");

数据被称为参数或占位符的某个 变量 替代。

请注意,完全相同的查询将发送到服务器,其中没有任何数据!然后,我们通过 第二个 请求发送数据,该请求实际上与查询本身是分开的:

$db->execute($data);

因此它不能更改我们的程序并造成任何伤害。
很简单-是吗?

我必须补充的唯一一件事是在每本手册中始终省略:

预处理语句只能保护 数据文字 ,但不能与任何其他查询部分一起使用。
因此,一旦我们不得不添加一个动态 标识符 (例如,一个字段名),准备好的语句就无济于事。



 类似资料:
  • 问题内容: 停止使用不推荐使用的mysql_ *函数后,我切换到mysqli。但是后来,我注意到未准备好的语句对于SQL注入是不安全的。然后,我再次更改了代码。 我所拥有的是以下函数,该函数检查数据库中是否存在变量 $ ID 并打印该行的 title 值: 我将其更改为: 我的问题是:这是执行准备好的语句的正确方法吗?另外,我现在可以安全使用SQL注入吗?非常感谢任何愿意回答这个问题的人:) 问题

  • 问题内容: 假设我有这样的代码: PDO文档说: 准备好的语句的参数不需要用引号引起来。司机为您处理。 那真的是我避免SQL注入所需要做的一切吗? 真的那么容易吗? 您可以假设MySQL会有所作为。另外,我真的只是对针对SQL注入使用准备好的语句感到好奇。在这种情况下,我不在乎XSS或其他可能的漏洞。 问题答案: 简短的回答是“ 否” ,PDO准备将不会为您防御所有可能的SQL注入攻击。对于某些晦

  • 假设上面的代码是我的查询。什么是一个安全的替代方案,将允许自动增加在mySQL数据库。

  • 问题内容: 在将输入数据放入MySQL数据库之前,我可以在Perl中使用该功能来清理输入吗?我不太了解正则表达式,所以在我做自己的功能之前,我想知道是否已经有一个正则表达式。 问题答案: 清理要插入数据库的数据的正确方法是对所有要插入SQL字符串的变量使用占位符。换句话说,永远不要这样做: 而是使用占位符: 然后在执行查询时传递要替换的变量: 您可以将这些操作与某些DBI便捷方法结合使用。上面也可

  • 问题内容: 我有一个使用准备好的语句的Doctrine_RawSql查询。但是,当生成SQL查询时,它们似乎会被忽略。但是,如果我忽略了标记值,则会得到关于不匹配的绑定变量数量的异常(因此,至少是试图将它们包含在内)。 如果我内联包含这些值,Doctrine是否在幕后做任何事情以防止SQL注入? 这是我的代码: 这提供了以下SQL输出: 编辑:上的属性已正确设置。如果我对参数进行硬编码: 我遇到了