防止恶意用户在添加操作时更新数据

时间:2015-06-08 22:16:57

标签: cakephp-3.0

这是一个基本的添加操作:

public function add()
{
    $article = $this->Articles->newEntity();

    if ($this->request->is('post')) {
        $article = $this->Articles->patchEntity($article, $this->request->data);

        if ($this->Articles->save($article)) {
            $this->Flash->success('Success.');
            return $this->redirect(['action' => 'index']);
        } else {
            $this->Flash->error('Fail.');    
        }
    }

    $this->set(compact('article'));
}

如果恶意用户在表单中注入名称为id的字段,并将此字段的值设置为2。由于用户执行此操作,因此ID值将位于$this->request->data,因此$this->Articles->patchEntity($article, $this->request->data)id修补此$this->Articles->save($article),而2将更新记录{{1}}创建新记录??

1 个答案:

答案 0 :(得分:5)

取决于

Entity::$_accessible

如果你烘焙模型,那么这不应该发生,因为主键字段不会包含在实体_accessible属性中,该属性定义了可以mass assigned when creating/patching entities的字段。(这种行为最近改变了)

如果你烘焙模型,那么这不应该发生,因为主键字段将被设置为在实体_accessible属性中不可分配,这意味着这些字段不能是通过mass assignment when creating/patching entities设置。

如果您没有烘焙模型并且没有定义_accessible属性,或者向其添加了主键字段,那么是,如果发布的数据进入修补机制,那么会发生什么,你将留下UPDATE而不是INSERT

安全组件

Security component会阻止form tampering,并拒绝修改后的表单请求。如果你使用它,那么表格数据首先不会进入add()方法。

还有fieldList选项

创建/修补实体时可以使用

The fieldList option来指定允许在实体上设置的字段。稀疏id字段,不能再注入。

$article = $this->Articles->patchEntity($article, $this->request->data, [
    'fieldList' => [
        'title',
        'body',
        //...
    ]
]);

最后,验证

Validation也可以防止注射,但这可能被认为有点不稳定。简单地返回false的自定义规则就是这样做,你可以创建一个额外的验证器,比如

public function validationAdd(Validator $validator) {
    return
        $this->validationDefault($validator)
            ->add('id', 'mustNotBePresent', ['rule' => function() {
                return false;
            }]);
}

然后可以在修补实体时使用

$article = $this->Articles->patchEntity($article, $this->request->data, [
    'validate' => 'add'
]);