我对参数化查询有几个基本问题
考虑以下代码:
$id = (int)$_GET['id'];
mysql_query("UPDATE table SET field=1 WHERE id=".$id);
现在使用参数化查询同样的事情
$sql = "UPDATE table SET field=1 WHERE id=?";
$q = $db->prepare($sql);
$q->execute(array($_GET['id']));
我的问题是:
(int)
演员)不安全的情况?$_GET['id']
转换为int?答案 0 :(得分:3)
是否存在第一个代码(即使用(int)强制转换)不安全的情况?
我不是PHP专家,但我认为不应该。这并不是说PHP没有可以在这里利用的错误(已知或尚未被发现)。
是第二段代码OK还是我还应该将$ _GET ['id']转换为int?
同样,第二段代码应该绝对正确 - 即使数据类型是一个字符串,MySQL也不会为SQL评估它,因为它是一个参数,因此只能被视为文字值。但是,在执行转换时肯定没有伤害(这可以避免MySQL处理参数的任何缺陷) - 我建议同时执行这两种操作。
编辑 - @Tomalak非常关注演员可能导致数据不正确,并建议首先使用is_numeric()
等健全性检查验证您的输入;我全心全意地同意。
第二段代码有任何已知的漏洞吗?也就是说,如果我使用第二个查询,是否有任何方式可以进行SQL攻击?
据我所知。
答案 1 :(得分:2)
(int)
会产生0
。这可能导致更新错误的记录。此外,当后面的查询变得更复杂时,它是草率的,并且是“忘记”正确类型转换的公开邀请。
以当前形式安装 (针对SQL注入,而不是更新错误的记录),但我仍然不推荐它。一旦查询变得更复杂,你无论如何都必须使用预准备语句,所以从一开始就这样做 - 也是为了保持一致性。
那也很邋..该参数将作为字符串传输到DB,DB将尝试将其强制转换。它是安全的(针对SQL注入),但除非您确切知道数据库服务器在传递无效数据时的反应,否则您应该预先清理该值(is_numeric()
并进行转换)。
没有。 (除非PDO中存在错误,否则。)
根据经验:
0
并且我没有ID 0
的记录,所以没关系。”你想法的一部分过程