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

时间:2011-12-08 13:19:49

标签: php sql database pdo code-injection

这是我正在准备的查询。这看起来太像普通的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. 通过声明安全获取订单的表名称,还是我应该 从输入中获取值?
  3. 目前我将代码更改为

    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);
    }
    

1 个答案:

答案 0 :(得分:1)

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

您可以使用$orderby清理mysql_real_escape_string()或拒绝$orderby的值,这些值不包含单个有效列名,后跟可选asc或{{1 (如果你愿意,甚至可以用逗号分隔的列表)。您可以通过硬编码或请求该表的列列表来确定有效列的列表(来自INFORMATION_SCHEMA)。

当然,您可以desc使用is_numeric()$page

有了这个,不仅可以覆盖sql注入,还可以使代码更加健壮。


小更新:如您所发现,您不能使用$pagesize的参数。