Security Issue in CakePHP

March 29th, 2008 by Nik Chankov Leave a reply »

I notice this recently when we start creating the security component of a project. The best way to explain the issue is to give an example:

Imagine that in your application you create an action “edit profile” where each user can change his personal details for the account. If course there will be fields for changing user’s real name, password, email etc., but the username field should be readonly.

The direct approach to create such page is to reuse “edit” action of the user’s controller, but instead of getting the ID from the url, it need to be fetched from the session’s auth variable. The second thing which you have to do is to remove “username” field from the view and you are done. :) Well, fast and easy, but not very secured…

What can be done? Well of course in the example above the “hacker” need to be logged in. So, the easiest approach is to go to profile page and using FireBug plugin to add a field on the fly with name data[User][username] and set value in it. After submitting if there are no additional checks, the username will be successfully changed. The worst example is instead of username the user change his security group … and on the next login he got admin privileges. Scary huh?

Of course CakePHP is rich framework and it’s possible to prevent such intrusion. In the Model there is a class variable called $whitelist. In this variable it’s possible to set fields which could be saved.

So bear in mind while you codding you applications and sites :)

Advertisement

15 comments

  1. Nice post. I didnt heard about $whitelist, it would be handy for sure.

  2. lqdice says:

    Actually the Security component prevents against this. No need to whitelist fields individually that is just too much work!

  3. Baz L says:

    Care to post an example of how the Security component helps with this?

  4. Mark says:

    i would certainly like to know about that, too.
    maybe it has to do with this array – somehow:
    although i dont see how this could get evoked automatically by the controller

    /**
    * Form fields to disable
    *
    * @var array
    * @access public
    */
    var $disabledFields = array();

  5. Mark says:

    nope.. i think i found it now..

    [__Token] => Array
    (
    [key] => 1a53278e1d8b97027738c099fad454393a70de9e
    [fields] => 6e149c4f100ad661c40b11e3dc6c7efca07d0e3b
    )

    as soon as you use this component, it automatically creates a token (together with your security salt).
    so as soon as sb tries to add fields – the token would not be valid anymore..

  6. Nik Chankov says:

    Thanks for the hint Mark, unfortunately while I tested this component I had problems with implementation – forms seems to be not valid and I couldn’t manage to fix it, so I never used :(
    Probably how is good time for this.

  7. Mark says:

    mabye some fixed bug by now…
    in inserts this in every form just by including the component in the app controller

    although i dont know if this is a good idea – there might be some occasion where you dont want to have it.
    i sure works well on static forms
    but it might result in trouble using ajax or innerHTML to append some new fields the form^^

  8. Mark says:

    well, i was kinda right.
    i does validate the form input based on the fields that are created by the FORM HELPER. so if you add some dynamically/manually (js/ajax etc), the POST result will be deleted and treated as “not safe”.

    so does anybody know how to turn security comp. off for a single action? this one has some dynamic field adding in it. all the rest of the controller actions are static – so no problem there..

  9. Yes Good info , I will trial

  10. Alice Hall says:

    Thanks for the information it will be a great help.

  11. tiffanys says:

    goog guy , so creative

  12. Meg Stefani says:

    i havent heard of the white list but seems to be a handy tool thnks for sharing the information.

  13. Pankaj says:

    HI thank for sharing suach a nice information

  14. Mihai says:

    To prevent this you could use:

    $this->Model->save($data, true, $fieldList = array(‘field1′, ‘field2′, ….)) instead

    $this->Model->save($data)

    Cheers.

  15. mark says:

    the whitelist ist not perfect…
    it only prevents from posting “too much” fields
    not “too less”

    so if somebody uses firebug to remove some “required” fields, it will then save this “invalid” post anyhow. which is a real pain in the rear.

    i invented a “requiredListing” in a modified app_model save() method in order to prevent this issue in any model where it is of great importance that the data is valid.

Leave a Reply