prepared statements如何帮助我们防止SQL injection次攻击?

维基百科说:

准备好的语句能够抵抗SQL注入,因为

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

推荐答案

这个 idea 非常简单——查询和数据被发送到数据库服务器separately

SQL注入问题的根源在于

实际上,我们的SQL查询是a legitimate program.

$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.

in case of prepared statements we don't alter our program, it remains intact

我们先向服务器发送program

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

其中数据被大约variable个参数或占位符所替代.

请注意,完全相同的查询被发送到服务器,其中没有任何数据!然后我们将数据与second请求一起发送,基本上与查询本身分离:

$db->execute($data);

所以它不能改变我们的程序,也不会造成任何伤害

我唯一需要补充的是,在每本手册中都会被忽略:

预处理语句只能保护data literals,但不能与任何其他查询部分一起使用

Sql相关问答推荐

Select 最大值,但当并列时,从其他列 Select 最大值

如何用3个(半)固定位置建模团队,并有效地搜索相同/不同的团队?

在SQL中将相同且紧挨着的元素进行分组

替换条件中的单元格值

如何隐藏聚合JSON数组元素的键

在Netezza SQL中将字符DataType转换为整型DataType

MySQL中的递归查询邻接表深度优先?

返回给定日期后的第 4 个工作日(不包括公众假期)

如何使用 Google BigQuery 中的条件根据特定列值连接列的 N 行?

根据要过滤的列的值进行联接和分组

没有调用子查询的嵌套 JOIN语法是什么?

删除每个不同日期中未 Select 的最短最长时间

如何在 case 语句中使用聚合?

每组使用平均值来填补缺失值的SQL

使用 PL/PGSQL 函数 Select 返回多条记录

如何对 SQL 表中的连续时间戳进行分组?

PlSql 陷入死循环

PostgresQL-根据另一列找到 3 个最低值

CURRENT_ROW 窗口框架上的 SQL 滞后

创建一个将层次 struct 级别放入列中的查询