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

Could you please tell if these 2 fragments of code secure in yii. Fragent 1:

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

Should I escape $target and $name in this query?

Fragment 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();

Should I escape $target and full_path here using CDbConnection::quoteValue() or something like this in these 2 fragments? I also one how to escape path in the Fragment 2 to avoid issues with special symbols used with LIKE (%, _).

I made changes to fragment 2 using binds and escaping %_:

$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();

Is it correct? Is there a more elegent way to do it?

dtg7662
dtg7662 我不太明白你的意思:“你需要绑定完整的字符串文字”
接近 7 年之前 回复
dsubq24666
dsubq24666 我添加了示例,我是如何重写片段2的。
接近 7 年之前 回复
dongwenhui8900
dongwenhui8900 您需要绑定完整的字符串文字
接近 7 年之前 回复
dthhlf1777
dthhlf1777 是的,链接rene的链接很有用。但是我想知道你对LIKE使用的变量是什么以及如何避免它的问题。在这种情况下绑定似乎不够,对吧?
接近 7 年之前 回复
dqyanc7264
dqyanc7264 toolong
接近 7 年之前 回复
doukan5332
doukan5332 你说的话根本没有意义。如果你知道的话,能否回答一下这个问题?你的言论现在绝对没用。
接近 7 年之前 回复
dor2p0520
dor2p0520 如果有人能够给出我能接受的完整答案,那将是很棒的。
接近 7 年之前 回复
dsds33222
dsds33222 我认为第一个片段是安全的,但第二个片段似乎并不安全。
接近 7 年之前 回复
douningqiu4991
douningqiu4991 toolong
接近 7 年之前 回复
dongzhi7763
dongzhi7763 使用绑定参数我猜yiiframework.com/doc/guide/1.1/en/...
接近 7 年之前 回复
doskmc7870
doskmc7870 你怎么想?
接近 7 年之前 回复

2个回答

Speaking of more elegant ways, you can always avoid named parameters, which will dramatically shorten your code:

$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]);
dtqie02844
dtqie02844 dev.mysql.com/doc/refman/5.0/en/...
接近 7 年之前 回复
douke6881
douke6881 为什么你也逃脱了?
接近 7 年之前 回复
duan111112
duan111112 我还没有检查过,但是他们在这里写了yiiframework.com/wiki/275/how-to-write-secure-yii-applications:“关于位置参数的附注截至目前(Yii 1.1.8),框架确实如此 未识别的标有“?”的位置参数。您必须使用名称以“:”开头的命名参数。“
接近 7 年之前 回复
doubi1713
doubi1713 yii的位置参数有什么问题?
接近 7 年之前 回复
douyan8961
douyan8961 在我看来,位置参数标有“?” 不会在yii中工作。
接近 7 年之前 回复

You have two options:

a) use a model object e.g in your case you can have model class for folder table and any other associated table where you are inserting/updating data. This will help you work with set of models (if that suits you ). Model class have built-in functions to validate data before inserting into data base . e.g CActiveRecord save method.Further read this for related security details

using lets say you have Folder model:

 $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) If creating model class is not desired, use Binding Parameters Details article ,see #5 Binding Parameters

Assuming you construct the $full_path and $path variables

  //$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();

hope this will be helpfull

duanbushi1479
duanbushi1479 如果混淆,答案会根据我们的讨论进行更新。 谢谢你在代码中指出了这个问题
接近 7 年之前 回复
douzhu6149
douzhu6149 我没有说{$ variable}是通过引用本身传递的,我的意思是如果你尝试执行你的代码它会失败,因为bindParam传递第二个参数作为参考。
接近 7 年之前 回复
dtxox60220
dtxox60220 让我们在聊天中继续讨论
接近 7 年之前 回复
dongya8378
dongya8378 阅读本文:php.net/manual/en/language.types.string.php以了解带有字符串的花括号。 它没有通过引用的东西传递它的STRING PARSING变量。
接近 7 年之前 回复
douchao5864
douchao5864 我在你的例子中对%的含义是什么:如果path包含%或_(可能),你的示例将无法正常工作,因为此符号对SQL LIKE运算符具有特殊含义。 你明白我的意思吗?
接近 7 年之前 回复
duanchu0031
duanchu0031 第二个参数用于引用,对吗?
接近 7 年之前 回复
dpca4790
dpca4790 public function bindParam($ name,&$ value,$ dataType = null,$ length = null,$ driverOptions = null){$ this-> prepare(); if($ dataType === null)$ this - > _ statement-> bindParam($ name,$ value,$ this - > _ connection-> getPdoType(gettype($ value))); elseif($ length === null)$ this - > _ statement-> bindParam($ name,$ value,$ dataType); elseif($ driverOptions === null)$ this - > _ statement-> bindParam($ name,$ value,$ dataType,$ length); else $ this - > _ statement-> bindParam($ name,$ value,$ dataType,$ length,$ driverOptions); $这 - > _ paramLog [$名] =&$值; 返回$ this; }
接近 7 年之前 回复
duannuci4008
duannuci4008 这是bindParam:
接近 7 年之前 回复
dtnqbre7980007
dtnqbre7980007 。并记住$ path参数不是通过引用传递的。 它的php构造为例如“我的名字是{$ first_name} {$ last_name}”来用字符串解析变量
接近 7 年之前 回复
doushaju4901
doushaju4901 ,这一切都取决于你想如何处理你的数据,我已经给你两个选项。 与其他模型和控制器一起使用时,模型最佳(比如在MVC架构中使用)。 第二种选择最适合您。 对于你逃避%的问题,我不确定你正在构建什么样的查询。 编写你想构建的计划sql查询我会试试。 如果你需要'path%'搜索试试这个:$ command-> bindParam(“:oldPath”,“{$ path}%”,PDO :: PARAM_STR);
接近 7 年之前 回复
dsfsd43523
dsfsd43523 使用更新数据似乎比读取数据然后更新数据更好,对吧?
接近 7 年之前 回复
donglian5309
donglian5309 3. $ command-> bindParam(“:oldPath”,“%{$ path}%”,PDO :: PARAM_STR); 不会工作,因为第二个参数是通过引用传递,对吗?
接近 7 年之前 回复
drtsd7864
drtsd7864 2. $ command-> bindParam(“:oldPath”,“%{$ path}%”,PDO :: PARAM_STR); 我需要LIKE路径%,而不是%path%。
接近 7 年之前 回复
doulu8847
doulu8847 1.为什么不在LIKE表达式中使用它来路径%,_?
接近 7 年之前 回复
dpthuyh1678
dpthuyh1678 我有模型文件夹和代码,我使用的是从其中一个方法调用。
接近 7 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐