Php 搜索查询的PDO SQL注入测试
我对使用PDO非常陌生,所以我不确定我是否正确地使用了它,但是通过下面的测试,我能够进行一些我想绕过的注入 在我的模型课上,我有一些快捷方式。其中一个名为return_all($table,$order,$direction),它只返回表中的所有行:Php 搜索查询的PDO SQL注入测试,php,mysql,pdo,sql-injection,Php,Mysql,Pdo,Sql Injection,我对使用PDO非常陌生,所以我不确定我是否正确地使用了它,但是通过下面的测试,我能够进行一些我想绕过的注入 在我的模型课上,我有一些快捷方式。其中一个名为return_all($table,$order,$direction),它只返回表中的所有行: public function return_all($table,$order = false, $direction = false) { try { if($order == false) {
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\u real\u escape\u string()完全没有做任何事情,SQL仍然在运行,并在用户数组中创建了一个新用户
我还试图将表名设为绑定参数,但由于在表名周围添加了``PDO,因此我假设出现了一个sql错误
有没有更好的方法来完成下面的代码?您已经解决了方向问题
if($direction != false && !in_array($direction,array("ASC","DESC"))) {
$direction = "DESC";
}
对表名使用相同的方法
$allowed_tables = array('table1', 'table2');//Array of allowed tables to sanatise query
if (in_array($table, $allowed_tables)) {
$sql = "SELECT * FROM ".$table." ORDER BY :order ".$direction;
}
@summea,我尝试将:表设为绑定参数,但sql抱怨出现了sql错误。我认为这是由于PDO在表名周围加了``引号,如果不使用保留字作为表名,则不需要在表名周围加这些``引号。此外,我认为您不需要mysql_real_escape_string(),因为据我所知,PDO会在内部自动为您执行此操作xd@aleation:我可以肯定地确认,执行类似“SELECT*FROM:table_name ORDER BY:ORDER DESC”的操作会产生sql错误,而上面的示例不会。sql错误为:SQLSTATE[42000]:语法错误或访问冲突:1064您的sql语法有错误;检查与您的MySQL服务器版本对应的手册,以了解在第1行“创建日期”附近使用的“用户”顺序的正确语法,该return_all()函数有什么意义?看起来您的表充当某种排序的纯文本文件,而不是数据库。为什么不让此函数接受任意查询(以及要绑定的参数)?不能绑定SQL查询的结构元素,只能绑定SQL将要操作的值。您不能绑定列或表名。它在那里,但不是formtted@davidstrachan,嘿,大卫,谢谢你的回答。这是最安全的方法。我想写一些完全动态的东西,这样我就不需要在每个项目中更改它,但我现在也意识到,这种函数存在大量潜在的安全问题,因此肯定需要一点安全性。