如何使用CakePHP防止参数中的SQL注入

bpsygsoo  于 2022-11-11  发布在  PHP
关注(0)|答案(3)|浏览(179)

使用从用户输入接收的参数时,如何在从数据库提取数据时防止SQL注入:

if(isset($_GET['cityval']) && $_GET['cityval'] !=''){

    $city = $this->request->query('cityval'); 

      $searching .= " and college_city in ($city) ";
    } else {
        $searching .= "";
    }
    if(isset($_GET['scholarship']) && $_GET['scholarship'] !=''){
        $searching .= " and college_scholarship = '".$_GET['scholarship']."' ";
    } else {
        $searching .= "";
    }

我的主要疑问如下

$search = $this->Search->query("select * from  colleges where college_id!='' and status='active' $searching order by $order desc limit $start, 10 ");
tjjdgumg

tjjdgumg1#

**不要使用原始查询。**只需使用CakePHP提供的查询生成器,它将为您防止注入。请参阅在线CakePHP书籍了解更多信息。

在CakePHP中使用原始查询是非常罕见的。

mm5n2pyu

mm5n2pyu2#

你要做的显然是通过获取参数来搜索。有一个很棒的插件可以让搜索变得很容易https://github.com/FriendsOfCake/search
实际上,使用插件就可以做到这一点:

$query = $this->Colleges->find('search', [
    'search' => $this->request->query
]);
$this->set('results', $this->Paginator->paginate($query));

搜索参数本身将在模型层处理,请查看插件文档。框架将负责净化输入。

tjrkku2a

tjrkku2a3#

看起来Cake ORM使用PDO:
在底层,查询构建器使用PDO预处理语句,以防止SQL注入攻击。
参考:https://book.cakephp.org/3.0/en/orm/query-builder.html
不幸的是,您创建查询的方式很容易受到攻击,因为您既没有使用Cake ORM,也没有使用PDO预准备语句。
如果你想使用原始查询,你可以这样做来保护你的代码:

// Add this in the beginning of the file/code:
use Cake\Datasource\ConnectionManager;

// Replace connection_name with the name of your connection (maybe it's "default")
$connection = ConnectionManager::get('connection_name');

$bindList = [];

$city = $this->request->query('cityval');

// PDO as a limitation for the parameter markers. See in the comments below
$cityList = array_filter(explode(',', $city), function($item) {
     return preg_match('/^\d+$/', $item);
});

$csvCity = implode(',', $cityList);

$scholarship = $this->request->query('scholarship');

if (!empty($csvCity)) {
    $searching .= " and college_city in ($csvCity)";
}

if (!empty($scholarship)) {
    $searching .= " and college_scholarship = :scholarship";
    $bindList['scholarship'] = $scholarship;
}

$stmt = $connection->prepare($searching);
$stmt->bind($bindList);
$stmt->execute();

// Read all rows.
$rows = $stmt->fetchAll('assoc');

// Read rows through iteration.
foreach ($rows as $row) {
    // Do work
}

PDO有一个局限性,因此没有合适的方法在预准备语句中使用SQL IN()子句(将值绑定到它),因此我们需要手动解析该子句中的值,就像我在代码中所做的那样。
PDO Prepare手册页:
注:参数标记只能表示完整的数据文本。文本的一部分、关键字、标识符或任何任意查询部分都不能使用参数绑定。例如,不能将多个值绑定到SQL语句的IN()子句中的单个参数。

参考资料

相关问题