防止恶意用户在添加操作时更新数据
Preventing malicious users update data at add action
这是一个基本的添加操作:
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
将被更新的创造新记录??
视情况而定。
Entity::$_accessible
如果您烘焙了模型,则不应发生这种情况,因为主键字段不会包含在定义字段的实体 _accessible
属性 中可以是 mass assigned when creating/patching entities.(这种行为最近发生了变化)
如果您烘焙了模型,那么这不应该发生,因为主键字段将在实体 _accessible
属性 中设置为不可分配,这意味着这些字段不能通过 mass assignment when creating/patching entities.
设置
如果您没有烘焙模型并且没有定义 _accessible
属性,或者向其中添加主键字段,那么是的,以防发布的数据到达补丁机制,那么这就是将会发生的事情,你将得到一个 UPDATE
而不是 INSERT
.
安全组件
Security component will prevent form tampering,并拒绝修改表单的请求。如果您要使用它,那么表单数据首先不会进入 add()
方法。
还有 fieldList
选项
The fieldList
option 可以在 creating/patching 实体时使用,以指定允许在实体上设置的字段。稀疏掉id
字段,就不能注入了
$article = $this->Articles->patchEntity($article, $this->request->data, [
'fieldList' => [
'title',
'body',
//...
]
]);
最后,验证
Validation 也可以防止注入,但是这可能被认为有点靠不住。一个简单的 returns 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'
]);
这是一个基本的添加操作:
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
将被更新的创造新记录??
视情况而定。
Entity::$_accessible
如果您烘焙了模型,则不应发生这种情况,因为主键字段不会包含在定义字段的实体 (这种行为最近发生了变化)_accessible
属性 中可以是 mass assigned when creating/patching entities.
如果您烘焙了模型,那么这不应该发生,因为主键字段将在实体 _accessible
属性 中设置为不可分配,这意味着这些字段不能通过 mass assignment when creating/patching entities.
如果您没有烘焙模型并且没有定义 _accessible
属性,或者向其中添加主键字段,那么是的,以防发布的数据到达补丁机制,那么这就是将会发生的事情,你将得到一个 UPDATE
而不是 INSERT
.
安全组件
Security component will prevent form tampering,并拒绝修改表单的请求。如果您要使用它,那么表单数据首先不会进入 add()
方法。
还有 fieldList
选项
The fieldList
option 可以在 creating/patching 实体时使用,以指定允许在实体上设置的字段。稀疏掉id
字段,就不能注入了
$article = $this->Articles->patchEntity($article, $this->request->data, [
'fieldList' => [
'title',
'body',
//...
]
]);
最后,验证
Validation 也可以防止注入,但是这可能被认为有点靠不住。一个简单的 returns 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'
]);