zen of coding

CakePHP and save() security

An interesting point came up on IRC…

What happens if someone submits data to your application via a fake form?

How can you ensure that a malicious user will not simply save some unwanted data by filling your $this->data array with things you don’t want there? For example, by sending an “extra” field, one could post $this->data[‘User’][‘id’] = 5; and trigger an update instead of save… well you can use your imagination to come up with some other evil tricks.

A simple solution is to ensure that you pass a third parameter to your save() method. If you take a look at the API, you’ll see that save() will allow you to specify a list of fields, which you know should be saved, the rest will be ignored. 

P.S. Additional security for your forms (and ultimately your data) can be achieved with the Security component.

  • In any situation where you have content ownership, you should always validate that data before saving. And as you mentioned, specifying safe fields for saving is a good idea, too. :)

  • Pingback: This week in Cake #2 | Personal weblog of Robert Beekman()

  • luke

    hi if I whitelist certain fields in a save call, (using $fields…) will the other fields I am not passing still be subject to validation? I imagine they will?

  • teknoid

    @luke

    Yes, the validation still takes place.

  • The proposed solution is interesting, but to me it has two important issues:

    1.- When saving long forms with many fields, you have to manually whitelist most of them, which makes the code dirtier (long arrays).

    2.- When adding fields to the database and the view, you may forget to manually whitelist then in the save() call.

    Therefore, I still prefer the good old way in many situations:

    $this->data[‘User’][‘id’] = $this->Session->read(‘Auth.User.id’);
    $this->Company->save($this->data);

    This overwrites any malicious input, if any, in the User.id field.

  • teknoid

    @Jaime Gómez Obregón

    Thanks for pointing that ticket out.

    Regarding the User.id, that would work if you needed to do an update, but in my example if I intended to save a new user the id field should not be present, or else an update would trigger…

    But I really wanted to just point out that such feature (white-listing of fields) is available and should be used to ensure that you always save exactly what you intend to.

  • Thanks for the post. There are loads of great bits of Cake built in that allow you to really secure an application, but sometimes I don’t think they are given enough attention.

  • teknoid

    @John

    Thanks for your response. True, there are some great “hidden” features of cake, but nowadays we can all add a little to the manual to point out all of the important features.

  • There’s also the SecurityComponent::$disabledFields, that would disallow setted fields and blackhole any attempt to post them

  • @rafaelbandeira3

    Yep, but the failure is kinda ugly in that case. Although I did provide some insight on how to make it “better” in another post ;)

  • gravyface

    I can’t recall the name or whether it was a validation rule or part of the model setup, but you could specify whether a field was allowed to be present during an update or insert. Anyone?

  • gravyface

    it was a validation rule: ‘on’ (create|update). But that’s not going to help if malicious users try to force an update. I like the hash method; simple and sassy.

  • @gravyface

    Yep, the ‘on’ key is to make sure when the validation actually gets triggered.
    I did update the post on the Security component slightly, so it’s even more simple to use now :)

%d bloggers like this: