在处理从另一个查询中获取的可信数据时,是否需要准备好的语句?
例如。
用户在整个站点中导航时,他们单击如下命名的链接:/?category=health
,其中health
是发送到数据库的值。
在这种情况下,我当然使用如下准备好的语句:
$qry = $dbh->prepare('SELECT category_id, and, other, columns FROM categories WHERE query_value = ?');
$qry->execute([$_GET['category']]);
$get = $qry->fetch();
$qry = null;
但是在脚本的更下方,我将基于从上一个查询中获取的categories.category_id
显示与所选类别相关的内容。
$Banners = $dbh->query('SELECT image FROM Banners WHERE category_id = '.$get['category_id'])->fetchAll();
我想这是一个安全的查询。
该值不能不是受信任的值,因为它必须是前一个查询的结果?
如果先前的查询未返回true,则不会执行此查询。
到目前为止,这是我的做法:
这是3排线。但是,如果我确定上面的1-liner也可以的话,它会加快编码部分的速度。
$qry = $dbh->prepare('SELECT image FROM Banners WHERE category_id = ?');
$qry->execute([$get['category_id']]);
$Banners = $qry->fetchAll();
答案 0 :(得分:2)
这主要是关于确保您的SQL语法是合理的以及您认为的语法是什么。防止恶意攻击只是其必然结果。如果将来您的类别ID产生撇号或其他不属于常规值的内容怎么办?无论如何,您都需要转义以获取正确的语法,或者更好地是准备好的语句。
其次,存在二阶注入,其中先前被视为不安全的值现在突然被视为安全,即使它仍然具有攻击的可能性。例如。如果您的值合法包含撇号。
更广泛地说:如何确保值是“安全的”?
// $get['category_id'] is safe and doesn't need escaping
'SELECT image FROM Banners WHERE category_id = '.$get['category_id']
好吧,你怎么知道的?哪些代码可确保此值安全?这个价值从何而来?您确定是它的来源吗?您要将此处查询的完整性外包给代码的其他部分。您如何确保其他部分正确地工作?现在,还是将来,经过大量重构? 通过以安全的方式编写查询来确保自己在生成正确的查询,不要将安全性外包。
您需要问自己:此查询是否易于按其编写方式进行注入?上面示例的答案是简单的是,它是$get['category_id']是您所认为的信任。