Securing Cakephp Forms including Ajax, JQuery & Security

While building a recent CakePHP solution in addition to securing my forms I needed to use some JQuery-driven Ajax calls. Although on the surface this appeared straight forward the documentation was lacking in the detail required. I wasted alot of time trying different things that didn’t work idependantly but once put together provided what I believe is a working solution. It may need some refinement over time but hopefully this will save others wasting so much time in code-wilderness.

In this post I will show the complete process of securing both user and ajax submitted forms in CakePhp 2.0. For the purposes of the demonstration, and not that they were needed at all, I have used the first steps of the introduction blog tutorial. I used the Posts as my only database table and baked up a Model, Controller and Views quickly using the console. If you are interested in the setup then dropdown to the section labelled setup for an explanation.

Step 1) Installing the CakePHP Security Component:

Add the Security component to your AppController. Security can protect your form in a number of ways including CSRF which is what I was most interested in.

Line 4 is the most important line here as we are actually including the Security component. The other remaining lines are just defaults for a AppController. You will notice the beforeFilter() function. You can add $this->Security->blackHoleCallback = 'blackhole'; to this function and then create a new function called blackhole that handles your errors. This is worthwhile as you want to give away minimal information in case someone is trying to be naughty. If Security is working successfully then you should see some added code at the bottom of all your forms as shown here in the green box for an Add Post Form.

Step 2) Creating an Ajax Form and submitting it with JQuery:

Getting a working Ajax Submission using JQuery is pretty simple but getting it to work now we’ve enabled the Security component is where I had most difficulty mainly due to poor documentation. What I needed to do from the beginining was to create a hidden form that I could serialize and not to push variables straight into a string e.g. line 5 – in other words the following did NOT work:

It appeared that what was needed was a form hidden from users that could be submitted by JQuery. For the purposes of this demonstration I have created this inside a view called ajaxdemo and added public function ajaxdemo() {} to my PostsController. You will note in this form I have not used $this->Form->hidden so you can see the fields. Also note in this example snippet I have two divs: one I use to trigger the Ajax submission; and another that shows some results.

AJAX TEST

Click here
Results Go Here

Add at the bottom of the page we can add the required javascript.

Step 3) Making it all work:

My recommedation at this point is to go back to your AppController and comment out the public $components = array('Security'); line so you can test your Ajax call without the interferrence of Security. However, I expect you, like me, want to just crack on with the business at hand so here goes.

If we try and make a Ajax call now should get binned by the Security component. However we can add a beforeFilter exclude in the form shown:

And update our tracker action to the following noting how we prevent a view error using the $this->autoRender = false; and check that we have a Ajax request.

Don’t forget to add var $components = array('RequestHandler'); to the top of our PostsComponent just under the class declaration.

You should now be able to test this and see the results of our simple sums added to the ajax_result div.

Other Considerations

1) Data Validation

Providing you have set up a model for this controller then it is easy to  ensure that everything is valid.   The model should contain all of the validation rules you wish to apply to the data in the model.   Providing you call the $this->Controller->save() function then the data is validated.

3) Data Sanitization

Check out the Sanitize Library.

4) Use NONCE for Security

If you are using the Security component you should find that the CSRF feature automatically expires after a settime thus rendering forms non-submitable after a period of time.

Set Up

This is how I set up the system for this demonstration. I’m assuming you have downloaded and set up a basic working CakePHP installation.

Step 1) In phpmyadmin (or similar database management tool) run the following SQL taken from the CakePHP Blog Tutorial for Version 2.

Step 2) In your command line run the following commands just accepting the default everytime except when it asks if you want to create some basic class methods.

You should now have worked through baking a Model, Controller (not forgetting the basic class methods) and some views. Check it works by going to http://yourdomain/posts

About CDB 361 Articles
Self-Employed Software Developer, Spark, Property Management, Hobby Forestry, Ex-Teacher, Engineering - Wood, Metal, Electrics & Computers. Outdoors - Walk, Cycle, Kitesurf,

1 Comment

  1. Hello, good post.
    You can still make secure ajax calls using Cake’s provided form security mechanics.
    To do this, render a non-visible form and place inputs to store the ajax call parameters. Then, with Javascript set these parameters in your form and do the ajax call by serializing it. Remember that if you have CSRF check enabled (and one-token-per-session is disabled) you will have to update the form with a new valid CSRF token (you can read it in the controller with $this->request->params['_Token']['key']).

    Example:

    Form->create(‘AjaxForm’);
    echo $this->Form->hidden(‘value’);
    echo $this->Form->end();
    ?>

    function makeAjaxCall() {
    $.post(
    ajaxUrl,
    $(‘#AjaxForm’).serialize(),
    function(data) {
    $(‘#AjaxForm [name=”data[_Token][key]”]’).val(data.newCsrfToken)
    }
    );
    };

    **For further reference, we have created a component that allows to maintain security enabled on client side forms that are dinamically modified, and removes the need to unlock fields or actions when making ajax calls. You can find it at https://github.com/QTSdev/DynamicSecurity.**

Leave a Reply

Your email address will not be published.


*


This site uses Akismet to reduce spam. Learn how your comment data is processed.