Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/230.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 安全地允许用户动态选择要搜索的数据库字段/条件_Php_Sql_Cakephp_Sql Injection - Fatal编程技术网

Php 安全地允许用户动态选择要搜索的数据库字段/条件

Php 安全地允许用户动态选择要搜索的数据库字段/条件,php,sql,cakephp,sql-injection,Php,Sql,Cakephp,Sql Injection,我正在扩展cakePHP 1.3.13网站,我的用户需要能够通过web应用程序实际生成自己的SELECT查询。他们以前确实在查询MS Access数据库,但现在必须使用表单控件通过网站进行搜索,但他们已经习惯了,并且需要一定程度的灵活性 他们正在搜索票证,有两个SELECT字段他们并不总是需要查看,还有两个WHERE条件他们并不总是需要筛选,我试图找出如何在不添加动态SQL安全整体的情况下允许该功能 以下是我的查找方法: $tickets = $this->Hauler->find(

我正在扩展cakePHP 1.3.13网站,我的用户需要能够通过web应用程序实际生成自己的
SELECT
查询。他们以前确实在查询MS Access数据库,但现在必须使用表单控件通过网站进行搜索,但他们已经习惯了,并且需要一定程度的灵活性

他们正在搜索票证,有两个
SELECT
字段他们并不总是需要查看,还有两个
WHERE
条件他们并不总是需要筛选,我试图找出如何在不添加动态SQL安全整体的情况下允许该功能

以下是我的查找方法:

$tickets = $this->Hauler->find('all', array(
        'conditions'=>array("ticketDate between'$startDate' and '$endDate'", "LocationID='$plant_id'", 'paid=0'),
        'fields'=>array('LocationID','OrderID','TicketDate','TicketNo','FreightPay','Qty','Total', 'Paid'),
        'order'=>array('TicketDate', 'LocationID','OrderID'),
        ));
我认为包含动态字段的唯一方法是使用
if
语句从预定义的一组字段组合中选择一个(不可扩展,令人讨厌),或者创建一个
$fields
数组以附加到
[fields]

这些条件也有类似的问题,我已经不喜欢在“$startDate”之间包含字符串连接,比如
,但我不知道还有更好的方法。如果我使用
find()
方法,那么就使用CakePHP,但我不确定效果如何

是否有一种特定的方法可以允许这些“动态”搜索而不使用实际动态SQL?我想继续使用CakePHP的“find()”方法,我知道存储过程允许我这样做,但在这种情况下,我需要代码中的逻辑。另外,除了Cake的
find()
方法在任何情况下所做的之外,我是否应该采取其他的消毒步骤

我只有两个非常值得信任的用户,所以在这个精确的搜索中,安全性不是最大的问题,但我真的很想知道如何正确地进行这种查找

更新:我已经按照@Anh Pham的建议更新了我的代码并解决了
字段
问题,但我仍然无法使可选的
条件
工作。这是我的新代码:

        $tickets = $this->Hauler->find('all', array(
        'conditions'=>array('Hauler.ticketDate BETWEEN ? AND ?' => array($startDate,$endDate), 'Hauler.LocationID'=>$plant_id, 'Hauler.paid'=>0),
        'order'=>array('TicketDate', 'LocationID','OrderID'),
        ));

如果没有通过表单提交LocationID,这将生成类似于
的查询,其中LocationID='
,而不是检查空字符串。如果没有提供LocationID,我希望我的查询省略
WHERE
子句的
LocationID=
部分。

我假设您总是在一个名为字段的文本上搜索。。。我建议将“to search”和“value”作为参数推送到存储过程中。在这里面,您可以清理并应用任何需要验证的规则。

首先:

$tickets = $this->Hauler->find('all', array(
  'conditions'=>array('Hauler.ticketDate BETWEEN ? AND ?' => array($startDate,$endDate), 'Hauler.LocationID'=>$plant_id, 'Hauler.paid'=>0),
  'order'=>array('TicketDate', 'LocationID','OrderID'),
));
用户只能看到您输出的字段,而不是结果中的所有字段
创建一个$fields数组以附加到[fields]键,这显然是不安全的。
我看不出这有多不安全


Cake's find()可以防止SQL注入。因此,我并不认为这里存在安全问题。

在本例中,我希望坚持使用CakePHP的
find()
方法,我应该指定该方法;存储过程在这种情况下可以工作,但我不希望站点上的每个表单都有存储过程。对于字段,我通常不希望提取比我想要操作或输出的字段更多的字段,但是,我与之交互的一些表有几十列,尽管到目前为止,我仅通过有限的视图与这些表交互。由于我知道所有可能需要的字段,因此仅在显示时限制它们是有意义的。在这种情况下,您可以安全地设置$fields数组。只要您使用Cake ORM函数,就可以避免SQL注入。我尝试了
'hailer.LocationID'=>$plant\u id
数组样式的表示法,在您的回答中,我仍然会得到类似SQL的
和[hailer].[LocationID]='
如果在我的表单中省略LocationID,那么传递的值是数组的空索引,不是文本
'
空字符串。否则我会根据你的建议计算出字段过滤器。