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

如何使用CakePHP防止参数中的SQL注入,php,cakephp,Php,Cakephp,当使用从用户输入接收的参数时,如何防止从数据库获取数据时发生SQL注入: if(isset($_GET['cityval']) && $_GET['cityval'] !=''){ $city = $this->request->query('cityval'); $searching .= " and college_city in ($city) "; } else { $searching .= "";

当使用从用户输入接收的参数时,如何防止从数据库获取数据时发生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 ");

似乎蛋糕ORM使用PDO:

在封面下,查询生成器使用PDO准备的语句 可以防止SQL注入攻击

参考:

不幸的是,您创建查询的方式很脆弱,因为您没有使用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()
子句(将值绑定到它),所以我们需要像我在代码中做的那样手动解析该子句中的值

从手册页面:

注意:参数标记只能表示完整的数据文字。 既不是文字的一部分,也不是关键字,也不是标识符,也不是任何东西 可以使用参数绑定任意查询部分。比如你 无法将多个值绑定到in()子句中的单个参数 SQL语句的类型

参考资料


不要使用原始查询。只需使用CakePHP提供的查询生成器,就可以防止注入。有关更多信息,请参阅联机CakePHP手册


很少需要在CakePHP中使用原始查询。

开始实际使用框架,或者根本不使用框架。您没有使用请求对象,没有使用ORM,您正在使用框架。从您的代码中可以清楚地看出,您没有花时间阅读手册

WComnisky的答案有大量非必需的代码,这个答案也不是以预期的方式使用框架

如果您关心创建一些编写良好的代码,那么您真的应该从编写官方文档的博客教程开始。如果没有,停止阅读,按照wcomniskys的建议去做。它可能会工作,但它不是好代码,也不是使用框架的正确方法,也不是最简单的解决方案。如果你对正确做事没有兴趣,你现在可以停止阅读了


您尝试做的显然是通过获取参数进行搜索。有一个很好的插件,使它非常容易

实际上,使用插件可能很容易:

$query = $this->Colleges->find('search', [
    'search' => $this->request->query
]);
$this->set('results', $this->Paginator->paginate($query));
搜索参数本身将在模型层中处理,请查看该层的插件文档。框架将负责对输入进行消毒


以上要求您真正理解框架的基本知识,并且知道自己在做什么。如果您出于任何原因对不使用框架提供的内容不感兴趣,那么最好不要使用它,因为这样会堆积无法维护的代码并导致开销。

hi这将返回一个数组,您如何将数组放入queryif(!empty($city))中{//PDO作为参数标记的限制。请参见下面的注释$cityList=array_filter(explode(',',$city),function($item){return preg_match('/^\d+$/',$item);});$search.=“and college_city in($cityList);}我刚刚更新了代码。很抱歉,我忘了添加内爆()由于我没有运行/测试该代码,如果有人再次通过1',则会对city阵列进行验证。请测试。