这个查询注入证明吗?
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();
【讨论】:
以上是关于这个查询注入证明吗?的主要内容,如果未能解决你的问题,请参考以下文章