我对使用 PDO 还是很陌生,所以我不确定我是否正确地将其关闭,但是通过以下测试,我可以进行一些我想绕过的注入。
在我的模型类中,我有一些快捷方法。其中之一称为 return_all($table,$order,$direction) ,它只返回表中的所有行:
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;
}
这很好用,除非我将以下内容作为 $table 传递给方法:
$table = "table_name; INSERT INTO `users` (`id`,`username`) VALUES (UUID(),'asd');";
现在不太可能有人能够更改 $table 值,因为它被硬编码到我的控制器函数中,但是,我有点担心即使我使用 PDO 仍然能够进行一些注入。更令人惊讶的是 mysql_real_escape_string() 完全没有做任何事情,SQL 仍然运行并在 users 数组中创建了一个新用户。
我还尝试将表名设置为绑定参数,但由于在表名周围添加了 ``PDO,我假设出现 sql 错误。
有没有更好的方法来完成下面的代码?