I'm pretty new to using PDO so I'm not sure if I have it down correctly, however with the following test I'm able to do some injection which I would like to bypass.
In my models class I have some shortcut methods. One of them is called return_all($table,$order,$direction) which simply returns all rows from a table:
public function return_all($table,$order = false, $direction = false) {
try {
if($order == false) {
$order = "create_date";
}
if($direction != false && !in_array($direction,array("ASC","DESC"))) {
$direction = "DESC";
}
$sql = "SELECT * FROM ".mysql_real_escape_string($table)." ORDER BY :order ".$direction;
$query = $this->pdo->prepare($sql);
$query->execute(array("order" => $order));
$query->setFetchMode(PDO::FETCH_ASSOC);
$results = $query->fetchAll();
} catch (PDOException $e) {
set_debug($e->getMessage(), true);
return false;
}
return $results;
}
This works fine, except, if I pass the following as $table into the method:
$table = "table_name; INSERT INTO `users` (`id`,`username`) VALUES (UUID(),'asd');";
Now it's unlikely that someone will ever be able to change the $table value as it's hard-coded into my controller functions, but, i'm a little concerned that I'm still able to do some injection even when I use PDO. What's more surprising is that the mysql_real_escape_string() did absolutely nothing, the SQL still ran and created a new user in the users array.
I also tried to make the table name a bound parameter but got a sql error I assume due to the `` PDO adds around the table name.
Is there a better way to accomplish my code below?