Daniel Faria
Daniel Faria

Reputation: 1484

Preventing malicious users update data at add action

Here is a basic 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'));
}

If a malicious user injects at form a field with name id and set the value of this field to 2. Since the user do that the id value will be in $this->request->data so at $this->Articles->patchEntity($article, $this->request->data) this id will be patched and at $this->Articles->save($article) the record 2 will be updated instead of create a new record??

Upvotes: 1

Views: 370

Answers (1)

ndm
ndm

Reputation: 60473

Depends.

Entity::$_accessible

If you baked your models, then this shouldn't happen, as the primary key field will not be included in the entities _accessible property, which defines the fields that can be mass assigned when creating/patching entities. (this behavior changed lately)

If you baked your models, then this shouldn't happen, as the primary key field(s) will be set to be non-assignable in the entities _accessible property, which means that these the fields cannot be set via mass assignment when creating/patching entities.

If you didn't baked your models and haven't defined the _accessible property, or added the primary key field to it, then yes, in case the posted data makes it to the patching mechanism, then that is what will happen, you'll be left with an UPDATE instead of an INSERT.

The Security component

The Security component will prevent form tampering, and reject requests with modified forms. If you'd use it, then the form data wouldn't make it to the add() method in the first place.

There's also the fieldList option

The fieldList option can be used when creating/patching entities in order to specifiy the fields that are allowed to be set on the entity. Sparse out the id field, and it cannot be injected anymore.

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

And finally, validation

Validation can prevent injections too, however that might be considered a little wonky. A custom rule that simply returns false would for example do it, you could create an additional validator, something like

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

which could then be used when patching the entity like

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

Upvotes: 4

Related Questions