Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 搜索查询的PDO SQL注入测试_Php_Mysql_Pdo_Sql Injection - Fatal编程技术网

Php 搜索查询的PDO SQL注入测试

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) {

我对使用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\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,嘿,大卫,谢谢你的回答。这是最安全的方法。我想写一些完全动态的东西,这样我就不需要在每个项目中更改它,但我现在也意识到,这种函数存在大量潜在的安全问题,因此肯定需要一点安全性。