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

时间:2011-11-01 19:52:32

标签: php sql cakephp sql-injection

我正在扩展cakePHP 1.3.13网站,我的用户需要能够几乎通过网络应用程序对某些数据生成自己的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语句来选择一组预定义的所有可能字段组合(不可扩展,烦人)或创建{{1} }数组附加到$fields键。

条件有类似的问题,我已经感到不舒服,包括像[fields]这样的字符串连接,但我不知道那里有更好的方法。 CakePHP claims they sanitize for me如果我使用between '$startDate'方法,但我不确定如何。

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

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

更新:我已根据@Anh Pham的建议更新了我的代码并解决了find()问题,但我仍然无法使用fields可选项。这是我的新代码:

conditions

如果未通过表单提交LocationID,则生成 $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'), )); 之类的查询,而不是检查空字符串我希望我的查询省略WHERE LocationID=''子句的LocationID=部分如果没有提供LocationID。

2 个答案:

答案 0 :(得分:1)

首先:

$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'),
));

用户只能看到您输出的字段,而不能看到结果中的所有字段。 create a $fields array to append to the [fields] key, which is obviously unsafe.我不知道它是如何不安全的。

Cake的find()可以防止SQL注入。所以我在这里看不到安全问题。

答案 1 :(得分:0)

我假设你总是在一个文本命名字段上搜索...我建议将“搜索”和“值”作为存储过程的参数。在其中,您可以清理并应用验证所需的任何规则。