Adding security to your CakePHP application – Part 2

In the Part 1 of this post, we've discussed how to secure your CakePHP application by following some thumb rules and using Sanitize class. Now, in the second part, we'll discuss how to add some more security to your application by using the nice Security component of CakePHP.

Before coming down to the nitty-gritty of the Security component, let us see why one should use the Security component in our application. When I started web programming with Cake, I used web forms to create, read, update and delete data. But at that time, being a beginner, I really didn't care about security of the web forms as they are responsible for the communication between client and server. Later, I found that so many (weird) things may happen in between, if a developer neglects some possible security flaws in his application.

I'll be trying to explain the scenario with the help of a case and its solution.

Case:

Let us consider the basic example of 2-tier architecture (employs only two types of hosts: clients and servers). Now whenever the data is transferred from the server to client, let us say a web form asking some information to process something, then that data can be easily modified by saving that form locally and modifying some attributes of that form. This form can be easily submitted back to the server by inputting some unexpected values. And it is better not to think about what (weird thing) can happen later on, if input from (the malicious) user is not filtered properly. By this way, the web forms can be easily tampered or spoofed leaving your application unprotected.

Solution:

The ultimate solution over this problem is to keep track of the data before it gets sent to the client by calculating the hash of the form fields. If the form attributes get altered, then ultimately the hash will also gets changed resulting the mismatch of the hashes after the form submission. This is what the Security Component in CakePHP exactly does!

The Security component will create a hash based on the form fields produced by our Form Helper. If someone tampers with the form fields (by adding or removing or changing any field), the hash is not going to match with the expected one and call to the form action will get fail.

So far, so good. Let us see an example.

In my basic Blog application, I need to provide security to my comments section as many users leave comments using this section and may pass some malicious data from right here. So, I'll go ahead and add a Security component in my CommentsController as follows:

PHP:
  1. class CommentsController extends AppController
  2. {
  3.     var $name = 'Comments';
  4.    
  5.     var $components = array('Security');
  6.    
  7.     public function add()
  8.     {
  9.         if (!empty($this->data)) {
  10.             $fieldList = array(
  11.                           'name',
  12.                           'email',
  13.                           'comment',
  14.                          );
  15.             $this->Comment->save($this->data, $fieldList);
  16.         }
  17.     }//end add()
  18.    
  19. }//end class

If $fieldList is not supplied, a malicious user can add additional fields to the form data (if you are not using Security component), and by this, change fields that were not originally intended to be changed. Hence it is a good practice to always pass an array of $fieldList while you save the data.

And guess what.. Our form is secured by this step. How??? It is just because we've added a single line in the controller where we've added the Security component. Now, the next step is to create a simple view add.ctp to add a comment which will consist of the three fields 'name', 'email' and 'comment'.

PHP:
  1. echo $this->Form->create('Comment', array('url' => array('action' => 'add'));
  2. echo $this->Form->input('name');
  3. echo $this->Form->input('email');
  4. echo $this->Form->input('comment');
  5. echo $this->Form->end(__('Submit', TRUE));

Lets us see what it actually does. The Security component works in conjunction with the FormHelper. It automatically inserts the hidden token fields into the form and checks it. In addition, it will not allow the form to be submitted after certain period of inactivity, depending upon the setting of Security.level in core.php file. If the form gets tampered then the application will return a blank screen in most cases unless and until we handle that error and display a custom message to the user. Basically, if the action is restricted by the security component, then it is black holed (black listed for that moment) and results into HTTP 404 error. And we can handle this thing by using the blackHoleCallback property of the Security component in the beforeFilter action.

PHP:
  1. //This function gets called before any action in the controller gets called
  2. public function beforeFilter()
  3. {
  4.     $this->Security->blackHoleCallback = 'error';
  5. }
  6.  
  7. //This function is called by the blackHoleCallback property of security component
  8. public function error()
  9. {
  10.     $this->cakeError('accessDenied');
  11. }//end fail()

In the error method, we are just calling the error method named accessDenied which will be responsible to display some nice error message. For that, you'll need to define this action in the app_error.php file in your /app directory. This is the place where you can define your customized error handling functions. Create this file if you do not have one.

PHP:
  1. class AppError extends ErrorHandler
  2. {
  3.     public function accessDenied()
  4.     {
  5.         $name = array('name' => __('You are not authorized to perform this action', TRUE))
  6.         $this->controller->set($name);
  7.  
  8.         $this->_outputMessage('denied');
  9.     }//end accessDenied()
  10.    
  11. }//end class

And now the very last step is to create the denied.ctp file which is the view file for our error message. Path of this file will be app/views/errors/denied.ctp.

PHP:
  1. <h2><?php echo $name; ?></h2>
  2. <div class="error">
  3.     <strong><?php __('Access Denied!'); ?></strong>
  4. </div>

In this way, if the form gets tampered, the malicious user will get the error message as mentioned above. The Security component has some more nice properties and methods which provides developers some additional features like secure SSL authentication and many more things which are very simple and handy to use.

Conclusion:

  • Being a framework, cake provides its own features such as Data validation, Sanitization class, Auth component and last but not least the Security component, with the help of which we can make our application secure in real sense. It is us.. the developers, who need to use the correct tools at correct time to make the defense stronger.

UPDATED:

  • Corrected signature of the _outputMessage()

About Rohan Faye

Rohan is a Computer Science and Engineering graduate and a PHP programmer by profession. He has just started working on the open source technologies and PHP frameworks. At SANIsoft, he is responsible to program and maintain high performance and scalable PHP based web applications. When not at work, you can find him day dreaming, reading books or watching international cricket matches.

6 Responses to Adding security to your CakePHP application – Part 2

  1. Arantxa August 9, 2010 at 1:32 pm #

    Hello,

    you have a mistake in

    $this->__outputMessage('denied');

    the correct name function is

    $this->_outputMessage('denied');

    Thank you for this post, it's very useful for me.

    Bye.

    • Rohan Faye September 13, 2010 at 3:13 pm #

      @Arantxa: Thanks for letting me know about the error in the function signature. Updated the code.

  2. leonardo September 17, 2010 at 6:06 pm #

    It's very userful.
    Thank you so much!
    When will it comes the Part 3, 4, 5... ?
    :P

    • Tarique Sani September 17, 2010 at 6:33 pm #

      What would you like to see in part 3? Security in CakePHP is easy ;-)

    • Rohan Faye September 19, 2010 at 11:47 pm #

      @leonardo Glad to know you found it useful. Keep reading. :)

Trackbacks/Pingbacks

  1. Tweets that mention Adding security to your CakePHP application – Part 2 at SANIsoft – PHP for E Biz -- Topsy.com - August 9, 2010

    [...] This post was mentioned on Twitter by Tarique Sani, Amit Badkas and Aditya Mooley, Rohan Faye. Rohan Faye said: #SANIsoft blog: Adding security to your CakePHP application – Part 2 http://bit.ly/9rvnH5 #cakephp [...]

Leave a Reply