Adding security to your CakePHP application – Part 1

Ben Parker once advised his young nephew Peter, whose super-hero alter ego is Spider-man, that “With great power comes great responsibility.” CakePHP framework provides us a rich tool-set to build high performance web applications. The applications built using CakePHP are secure at much extent as long as it comes with some nice features such as Authentication component and Access controlled lists.

But.. when it comes to develop high end commercial applications, some additional security measures must be taken to make your application robust as a matter of responsibility.

Alright. Now let us see how can we make our defense stronger.

With addition to use Authentication component and Access controlled lists, we should take help of Data validation and Data sanitization while building application in CakePHP. Validating data restricts user to provide the required input and of correct type. Server side validations are strongly recommended considering the form spoofing. But a drawback in only relying upon Data validation is it cannot sense the markup language and hence leaves your application open for the XSS (Cross Site Scripting) vulnerability.

To understand the various risks involved while developing PHP applications (without using any framework) and precautions to be taken to overcome the vulnerabilities, I recommend you to refer this presentation by Aditya Mooley.

To avoid the XSS vulnerability, CakePHP provides us the Sanitize class. It provides us the flexibility to filter data coming straight from the (malicious) user. As Sanitize class can be treated as a library, it can be used in the controllers and models as well.

As far as SQL injection is concerned, cake handles it auto-magically if you use Cake's ORM (Object Relational Mapping) methods such as find() and save() and proper array notation such as array('field' => 'value') rather than raw SQL.

So let us move ahead and see an example:

As your inner PHP programmer might have guessed, the very first step is to import the Sanitize class before the controller class definition :smile: .

PHP:
  1. App::import('Sanitize');
  2. class MyController extends AppController {
  3.     ...
  4.     ...
  5. }//end class

As you know that we have conventional PHP functions to escape strings to avoid XSS, but when it is framework, we've to follow its way to get the auto-magic functionality. So here are some methods from the Sanitizaion class to the rescue, which are very useful while dealing with the data sent by malicious user.

After importing the Sanitize class, you are free to use its functions statically.

1. Sanitize::paranoid(string $string, array $allowedChars);

If your are thinking to allow only alphanumeric characters from the user input, then paranoid function is a right way to move on. It simply stripes out the special characters from the user input. But still if you are kind enough to allow some special characters, use the $allowedChars array and pass the special characters to be ignored.

Demo:

PHP:
  1. $inputString = 'Joe, @#$!% does not work here!';
  2. echo Sanitize::paranoid($inputString);
  3. //output: Joedoesnotworkhere
  4. echo Sanitize::paranoid($inputString, array('!', ' '));
  5. //output: Joe does not work here!

2. Sanitize::html(string $string, array $options = array())

After watching how to eliminate the special characters, let us focus on how to eliminate the HTML characters from the input string so as to save our HTML page from the user by disturbing its layout or inserting new HTML code. You can simply follow the html function to achieve the same. It will convert the html characters present in the input into equivalent html entities. What??? you don't need to convert into equivalent entities, but delete the html characters present in the input string? Okay, just pass the 'remove' => TRUE in the options array and all done! Now you have the new input string with all the HTML characters filtered out :smile: .

Demo:

PHP:
  1. $inputString = '<strike>This string is not desirable</strike>';
  2. echo Sanitize::html($inputString);
  3. //output: &lt;strike&gt;This string is not desirable&lt;/strike&gt;
  4. echo Sanitize::html($inputString, array('remove' => TRUE));
  5. //output: This string is not desirable

3. Sanitize::escape(string $string, string $connection)

SQL injection is considered to be a serious security issue as far as form - database communication is concerned. Cake by default handles this vulnerability if you follow its ORM conventions, but when it comes to write custom queries, I highly recommend you to use this function. Depending on the system's current magic_quotes_gpc setting, the escape function escapes the SQL statements by adding slashes to the special characters.

$connection is the name of the database to quote the string for, as named in your app/config/database.php file.

Demo:

PHP:
  1. $inputString = "O'reilly";
  2. echo Sanitize::escape($inputString);
  3. //output: O\'reilly

4. Sanitize::clean(mixed $data, mixed $options)

The clean method takes a string or an array as input and returns the same string or array after it has been recursively "cleaned." The cleaning process covers a wide range of potential data problems, such as handing tricky backslashes, weird spaces, HTML, carriage returns, and more. It performs the following things:

  • Odd spaces (including 0xCA) are replaced with regular spaces.
  • Double-checking special chars and removal of carriage returns for increased SQL security.
  • Adding of slashes for SQL (just calls the sql function outlined above).
  • Swapping of user-inputted backslashes with trusted backslashes.

The $options argument can either be a string or an array. When a string is provided it's the database connection name. If an array is provided it will be merged with the following options:

  • connection
  • odd_spaces
  • encode
  • dollar
  • carriage
  • unicode
  • escape
  • backslash

Demo:

PHP:
  1. $this->data = Sanitize::clean($this->data, array('encode' => FALSE));

The above example will preserve the form data from encoding.

You can view these methods in cake/libs/sanitize.php to get a better handle on what's involved. You should never modify the base CakePHP files, however. It will make upgrading to future releases difficult and could cause unexpected behavior.

In the next part of this post, I'll try to explain the Cake's powerful Security component's functionality supported by some nice examples. Till then, have a great time and stay tuned :wink: !

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.

5 Responses to Adding security to your CakePHP application – Part 1

  1. red August 1, 2010 at 5:07 pm #

    Nice post, waiting for part 2.

    • Rohan Faye August 1, 2010 at 10:51 pm #

      @red Thank you. Part 2 is on the way.. :)

  2. Steve February 21, 2011 at 10:13 pm #

    Seems like the pivotal question is whether it's possible to ensure that Sanitize isn't overlooked by including it one time in the application controller rather than in each controller individually.

    • Rohan Faye February 24, 2011 at 5:23 pm #

      Above code is just an example. It completely depends upon the need of your application. If you need to ensure security for multiple modules of your application, then better to use the Sanitize class in the AppController. Else, simply import it wherever required to avoid loading the Sanitize class in each and every call.

Trackbacks/Pingbacks

  1. Adding security to your CakePHP application – Part 2 at SANIsoft – PHP for E Biz - September 13, 2010

    [...] security to your CakePHP application – Part 2 TweetIn the Part 1 of this post, we've discussed how to secure your CakePHP application by following some thumb rules [...]

Leave a Reply