这个查询注入证明吗?

Posted

技术标签:

【中文标题】这个查询注入证明吗?【英文标题】:Is this query injection proof? 【发布时间】:2011-03-29 01:52:04 【问题描述】:

我正在使用 PDO 与我的数据库通信,我想知道是否要转换这样的类型

$dbh->query("SELECT * FROM recipes WHERE id=".(int)$id);

足以防止sql注入?在这种情况下,$id 始终是一个整数。

我也想知道如果变量是字符串,那么在这种语句中防止注入的好方法是什么。

【问题讨论】:

最好的方法是使用参数化查询。 很抱歉提出一个愚蠢的问题,但在这种情况下我该怎么做呢? 最好的方法是使用参数化存储过程。 【参考方案1】:

不过要小心,在 php(int) 会将 NULL 转换为 0。

因此,如果您与应用程序中的 ID 0 有显着关联,则可能会无意中触发该值。

【讨论】:

(int) will convert NULL to 0 - $id = str_replace("\0", "", $id) 应该可以解决这个问题【参考方案2】:

是的,如果参数预期为整数,则绑定到整数足以防止 SQL 注入。

您也可以使用Automatic SQL Injection Tool 来检测它。

【讨论】:

【参考方案3】:

由于您专门将$id 转换为整数,因此它是安全的。对于字符串(或任何其他数据类型),您需要在执行查询之前对其进行转义;看看PDO::quote

【讨论】:

【参考方案4】:

由于您已经在使用 PDO,因此更好的方法是使用:

Prepared Statements

这样更好:

$dbh->prepare("SELECT * FROM recipes WHERE id = ?");
$dbh->bindParam(1, (int) $id);
// more code.....

【讨论】:

所以如果我使用它们,我不需要担心消毒任何东西? @Michael:消毒仍然是一个好主意,但是为了防止 sql 注入,准备好的语句要好得多。 我听说 PDO 默认会处理它。不是这样吗? @Michael:除非您使用 PDO 之外的准备好的语句。【参考方案5】:

您必须在查询中转义表名和字段名:

$dbh->query("SELECT * FROM `recipes` WHERE `id=`'".(int)$id."'");

【讨论】:

尝试改进的两个错误... :-O 这不是必须,除非它是一个关键字,但是是的,无论如何这样做是一个好习惯。【参考方案6】:

是的。强制转换为 int 可以防止所有令人讨厌的 SQL 注入可能性。

如果变量是一个字符串,你应该使用prepared statements来传递它。

$sql = 'SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour';
$sth = $dbh->prepare($sql);
$sth->execute(array(':calories' => 150, ':colour' => 'red'));
$red = $sth->fetchAll();

【讨论】:

以上是关于这个查询注入证明吗?的主要内容,如果未能解决你的问题,请参考以下文章

SQLi “百度杯”CTF比赛 九月场

这种动态 SQL 查询生成对注入安全吗?

我的 PDO 查询对 SQL 注入安全吗?

转义字符,SQL 注入

如何防止sql注入oracle apex

这个参数化查询如何防止 SQL 注入?