Search code examples
phppdoprepared-statementcode-injectionparameterized-query

Can I bind a parameter to a PDO statement as a comparison operator?


Is this code

class opinion
{
   private $dbh;
   var $opinionid,$opinion,$note,$actorid,$dateposted;
   var $isnew=FALSE;
   function loadby($column,$value,$operator="="){
       $dbh = new PDO(I deleted parameters here);
       $statement=$dbh->prepare("select * from fe_opinion where :column :operator :value");
       $statement->bindParam(":column", $column);
       $statement->bindParam(":value", $value);
       $statement->bindParam(":operator", $operator); //UNSURE, DOUBTFUL
       $statement->bindColumn("opinionid", $this->opinionid);
       $statement->bindColumn("opinion", $this->opinion);
       $statement->bindColumn("note", $this->note);
       $statement->bindColumn("actorid", $this->actorid);
       $statement->bindColumn("dateposted", $this->dateposted);
       $statement->fetch();
       return $statement->rowCount(); //please be 1
   }
}

injection safe?

       $statement->bindParam(":operator", $operator); //UNSURE, DOUBTFUL

Can I bind a parameter to a PDO statement as a comparison operator?


Solution

  • No, you cannot bind operators like that. As a workaround, you can dynamically create the "base" SQL query and use an operator whitelist (which is quite appropriate) to remain safe from injection:

    function loadby($column,$value,$operator="="){ 
       $dbh = new PDO(...); 
       $operator = getOperator($operator);
       if(!$operator) {
           // error handling
       }
       $statement=$dbh->prepare("select * from fe_opinion where :column $operator :value");
       // the rest like you already do it
    } 
    
    function getOperator($operator) {
       $allowed_ops = array('=', '<', '>'); // etc
       return in_array($operator, $allowed_ops) ? $operator : false;
    }
    

    Apart from this, the rest is fine and injection-proof "by definition".