是否在PDO注入中使用绑定参数构建查询安全


Is building queries with binding parameters in PDO injection safe?

这是我正在准备的查询。这看起来太像一个正常的mysql_query,我不确定我是否超出了PDO的安全边界。

function opinionlist($orderby="dateposted desc",$page="0",$pagesize="10"){
  $dbh = new PDO(...);
  $s = $dbh->prepare("select * from fe_opinion 
                       order by :orderby limit :page,:pagesize");
  $s->bindParam(":orderby", $orderby);
  $s->bindParam(":page", $page);
  $s->bindParam(":pagesize, $pagesize");
  $s->execute();
  $opinionlist = $s->fetchAll(PDO::FETCH_ASSOC);
  echo json_encode($opinionlist);
}
  1. 我可以安全地建立这样的查询吗?
  2. 获取order by语句的表名是否安全从输入中获取值?

当前我将代码更改为

function opinionlist($orderby="dateposted desc",$page="0",$pagesize="10"){
  $orderbylist=array("dateposted desc","countcomment desc","countvote desc");
  $dbh = new PDO(...);
  if(!in_array($orderby, $orderbylist)){$orderby="dateposted desc";}
  $s = $dbh->prepare("select * from fe_opinion order by $orderby limit :page,:pagesize");
  $s->bindParam(":page", $page);
  $s->bindParam(":pagesize, $pagesize");
  $s->execute();
  $opinionlist = $s->fetchAll(PDO::FETCH_ASSOC);
  echo json_encode($opinionlist);
}

验证输入的类型和内容是很好的做法。

您可以用mysql_real_escape_string()消毒$orderby,或者拒绝$orderby的值,这些值不是由单个有效列名后面跟着可选的ascdesc组成的(如果您愿意,甚至可以用逗号分隔这些列表)。您可以通过硬编码或请求该表的列列表(来自INFORMATION_SCHEMA)来确定有效列列表。

当然你也可以用is_numeric()代替$page$pagesize

有了这些,你不仅可以防止sql注入,还可以使你的代码更健壮。


小更新:正如您所发现的,您不能为$orderby使用参数