PDO 准备好的语句如何帮助防止 SQL 易受攻击的语句?

Posted

技术标签:

【中文标题】PDO 准备好的语句如何帮助防止 SQL 易受攻击的语句?【英文标题】:How PDO prepared statements help to prevent SQL vulnerable statements? 【发布时间】:2015-09-06 04:05:51 【问题描述】:

我很困惑,或者更确切地说,我对 pdo 准备好的语句感到非常困惑。我知道准备好的语句是保护数据免受黑客攻击的最佳方式。

发件人:How can prepared statements protect from SQL injection attacks?

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

$db->prepare("SELECT * FROM users where id=?");数据在哪里 替换为一些称为“占位符”的变量。

请注意,发送到服务器的查询是相同的,没有任何 里面的数据!然后我们用第二个请求发送数据, 与查询本身完全分离:

$db->执行($data);

查询-

$query=$db->prepare("SELECT * FROM USERS WHERE username=?");
$query->execute(array($tex));
$tex=blah; DROP TABLE users;--

然后它会像 - SELECT * FROM USERS WHERE username=blah; DROP TABLE 用户;--

prepare 语句将如何帮助我处理上面的这个例子?

如果这个问题理解模糊,我真的很抱歉。任何帮助,将不胜感激。提前致谢。

【问题讨论】:

【参考方案1】:

准备好的语句处理程序将确保绑定值始终用作有效的 SQL 值/文字(即 SQL 字符串或数字)并且从不用作'原始 SQL 文本'1.

这就是为什么占位符值不能用作列名或表名等标识符或充当其他 SQL 关键字的原因; 不能生成假设的易受攻击的查询。相反,它被视为如下:

WHERE username='blah; DROP TABLE users;--'
            --^ placeholder ensures valid SQL string value is used
            --  (note automatic/implicit addition of SQL quotes)

甚至在绑定“更棘手”的数据时:

$tex = "blah'; DROP TABLE users;--";  // embedded SQL quote character

它仍然是安全的:

WHERE username='blah''; DROP TABLE users;--'
            --^ placeholder STILL ensures valid SQL string value is used

因此,在使用占位符时,不可能生成易受攻击的 SQL(以这种方式)。

对于SQL Injection,查询的“形状”(包括关键字和标识符,但排除值)本身必须由输入更改。


1 从技术上讲,占位符值也可以通过单独的 数据通道(取决于适配器/驱动程序)发送,因此甚至可能不会出现在原始 SQL 查询本身中。

但是,考虑占位符为何安全或它们如何“工作”的简单方法是:

当使用占位符时,适配器确保“sql 真正安全转义”的等价物和适用的引用总是用于每个绑定的文本值 - 因此不可能意外忘记。

【讨论】:

您是说使用占位符时不可能生成易受攻击的 sql。但我想知道的是占位符是如何做那件事的?我的意思是 - htmlspecialchars() 函数将一些预定义字符(&,",',) 转换为 HTML 实体,addslashes() 函数返回一个在预定义字符前面带有反斜杠的字符串。像这些函数一样,占位符如何检测该值格式不正确或值不适合查询? 停止。它没有这样的事情。占位符确保值作为有效的 SQL 值提供。它与 HTML 或实体或斜线没有任何关系。占位符only 确保数据正确传输没有 SQL 注入的机会。 占位符永远不会改变实际值。在上面的示例中,我已经展示了如何使用正确的 (ANSI) SQL 语法在 SQL 查询中表示它。 (假设占位符构建实际的 SQL 查询,“方法”将使用 mysqli_real_escape_string 或等效项。)

以上是关于PDO 准备好的语句如何帮助防止 SQL 易受攻击的语句?的主要内容,如果未能解决你的问题,请参考以下文章

在 MySQL 中使用准备好的语句可以防止 SQL 注入攻击吗?

如何防止sql注入攻击?

使用 PDO 准备好的语句 MySQL 错误

如何查看准备好的 PDO SQL 语句 [重复]

SQL注入攻击的例子?

PDO - 使用准备好的语句将所有 sql 数据放入 html 表中