0

如何正确使用活动记录中的 updateall 方法?安全吗?我只是像这样使用它:

$rows = $this->updateAll($attributes, 'full_path = :path', array(':path' => $path));

但是这里的文档http://www.yiiframework.com/doc/api/1.1/CActiveRecord#updateAll-detail中写了关于它的内容:

使用指定条件更新记录。有关 $condition 和 $params 的详细说明,请参见 find()。请注意,不检查属性的安全性,也不进行验证。

这是否意味着我们很容易受到例如 sql 注入的攻击?我们需要在使用之前调用 validate 方法吗?如果使用绑定,使用 CDbCommand 的方法是否比使用 updateAll 更安全?预先感谢您的回答。我希望它们会有用。

4

2 回答 2

1

这是否意味着我们很容易受到例如 sql 注入的攻击?

如果您使用参数而不是查询字符串连接,则不会 - 这就是参数的设计目的。请参阅下面的注释。

我们需要在使用之前调用 validate 方法吗?

这取决于您是否需要验证模型属性中的值。

当您想以编程方式为多个项目切换布尔值时,您将如何在没有验证的情况下使用它的一个示例。

如果使用绑定,使用更安全吗?

使用参数与绑定有些相同——它还可以防止 SQL 注入。


笔记:

Yii 中的关键字 'safe' 不是指防止 SQL 注入,而是指当你批量设置/覆盖属性时,属性是否会复制到模型中。例如:

$model->attributes = $_POST['MyModel'];

在这里阅读更多:http ://www.yiiframework.com/wiki/161/understanding-safe-validation-rules/

于 2013-10-09T08:34:04.050 回答
1

sql injection 不,如果您使用第三个参数绑定参数,则该方法不易受到攻击。

此方法createUpdateCommandCDbCommandBuilder类调用,并且此方法将值绑定到准备好的语句,因此您不应该受到 SQL 注入的攻击

没有进行验证。

这意味着它不会根据您可以在模型中创建的验证规则来验证数据。因此,在调用此方法之前,您应该验证来自用户的所有数据是否正确(如果您存储一个 int,则传递的数据是一个 int,字符串少于 255 个字符,...)

由您决定是要调用该validate方法还是仅确保数据正常

不检查属性的安全性

这适用于 XSS 脚本等缺陷,无法控制您存储的文本可能包含一些 XSS 或其他不良 javascript。

更新

属性数组不安全?

属性数组是安全的。当您调用该updateAll方法时,它将在内部调用该createUpdateCommand方法CdbCommandBuilder

以下是该方法处理参数的方式:

foreach($data as $name=>$value)
{
    if(($column=$table->getColumn($name))!==null)
    {
        //Useless code for the example
        $fields[]=$column->rawName.'='.self::PARAM_PREFIX.$i;
        $values[self::PARAM_PREFIX.$i]=$column->typecast($value);
        $i++;
    }
}
//Some useless code for the example
$sql="UPDATE {$table->rawName} SET ".implode(', ',$fields);
$sql=$this->applyJoin($sql,$criteria->join);
$sql=$this->applyCondition($sql,$criteria->condition);
$sql=$this->applyOrder($sql,$criteria->order);
$sql=$this->applyLimit($sql,$criteria->limit,$criteria->offset);

$command=$this->_connection->createCommand($sql);
$this->bindValues($command,array_merge($values,$criteria->params));

如您所见,对每个参数执行了类型转换,以确保其类型应为应有的类型:$column->typecast($value);

然后它调用bindValues参数的方法

于 2013-10-09T08:37:57.517 回答