通过yii中的sql注入更新安全性

时间:2013-10-07 11:29:30

标签: php sql-injection yii

你能告诉你这两个代码片段是否在yii中安全。 Fragent 1:

 $numberOfRows = $this->updateAll(array('full_path' => $target, 'title' => $name,                'machine_name' => $name), 'full_path = :path', array(':path' => $path));

我应该在此查询中转义$ target和$ name吗?

片段2:

$sql = "UPDATE folders";
$sql .= " SET full_path = CONCAT('" . $target . "',SUBSTR(full_path, " . (strlen($path)  + 1) . ", LENGTH(full_path)-1))";
$sql .= " WHERE full_path LIKE '" . $path . "%'";
$command = $this->dbConnection->createCommand($sql);
$command->execute();

我应该在这里使用$ escape和full_path CDbConnection :: quoteValue()或这两个片段中的类似内容? 我还有一个如何在片段2中转义路径以避免与LIKE(%,_)一起使用的特殊符号出现问题。

我使用绑定和转义%_:

对片段2进行了更改
$sql = "UPDATE folders";
$sql .= " SET full_path = CONCAT(:target, SUBSTR(full_path, " . (strlen($path) + 1) . ", LENGTH(full_path)-1))";
$sql .= " WHERE full_path LIKE  :pathFilter";
$command = $this->dbConnection->createCommand($sql);

//escape %_ that can be used in SQL LIKE expression
$pathFilter = addcslashes($path, '%_') . '%';

$command->bindParam(":pathFilter", $pathFilter, PDO::PARAM_STR);
$command->bindParam(":target", $target, PDO::PARAM_STR);

$command->execute();

这是对的吗?有更优雅的方式吗?

2 个答案:

答案 0 :(得分:0)

说到更优雅的方法,您总是可以避免使用命名参数,这会大大缩短您的代码:

$sql  = "UPDATE folders SET";
$sql .= " full_path = CONCAT(?, SUBSTR(full_path, ?, LENGTH(full_path)-1))";
$sql .= " WHERE full_path LIKE ?";

//escape %,_ and \ that can be used in SQL LIKE expression
$pathFilter = addcslashes($path, '\%_') . '%'; // I've added a slash here

$command = $this->dbConnection->createCommand($sql);
$command->execute([$target, strlen($path) + 1, $pathFilter]);

答案 1 :(得分:0)

您有两种选择:

a)使用模型对象,例如在您的情况下,您可以拥有文件夹表的模型类      以及要插入/更新数据的任何其他关联表。这将帮助您使用一组模型(如果适合您)。 Model类具有内置函数,可在插入数据库之前验证数据。例如CActiveRecord save method。进一步read this了解相关的安全细节

使用假设你有Folder型号:

 $path='path to be updated';
 $criteria=new CDbCriteria;
  $criteria->compare('full_path',$path,true);
  $folder=Folder::model()->find($criteria);
  if($folder){
   $folder->attributes=$data;
    if($folder->save()){
      echo 'updated successfully';
    }else{
      echo 'invalid data';
    }
  }

b)如果不需要创建模型类,请使用Binding Parameters      Details article,请参阅#5绑定参数

假设你构造$ full_path和$ path变量

  //$full_path=[construct using php]
  //$path=[construct using php]
  $sql = "UPDATE folders SET full_path = :newPath  WHERE full_path LIKE :oldPath"
  $command = $this->dbConnection->createCommand($sql);
  $command->bindParam(":newPath", $full_path, PDO::PARAM_STR);
  $old_path=addcslashes($path,'%_').'%'; 
  $command->bindParam(":oldPath", $old_path, PDO::PARAM_STR);
  $command->execute();

希望这会有所帮助