这是一个基本的添加操作:
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}}创建新记录??
答案 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'
]);