How to handle security in POST or GET using CodeIgniter
Well… it’s a huge subject, and I don’t know if I’m the person to ask to regarding this subject, but a reader asked me to approach it. Let’s start with mentioning the features that CodeIgniter offer in this regard. Looking at the manual, we can clearly see that it covers a lot of subjects, including session handling, encryption, security, input, and form validation.
To talk about all these would take a lot of posts, so I think is better for everyone to rather read the manual (one of the best manuals out there).
How to handle GET data
The first line of defence when dealing with GET data can be found in the configuration file (application/config/config.php).
In there we can find a configuration parameter named “permitted_uri_chars” which, simply put, specifies which characters are permitted within the website’s URL:
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-=';
Usually, when I see messages written with big letters I pay greater attention. This happens here too, where the final comment is self explanatory: DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
You may also think that another configuration named “global_xss_filtering” will help you. XSS, or cross site scripting is a way through which someone can inject client-side scripts into web pages viewed by other users. Global XSS filtering would do the filtering to all types of requests (GET, POST or cookie). But, besides the fact that will slow your app (not by much, but still…), this doesn’t respect the mantra “filter input, clean output”. So you should use the XSS filter only on output.
After this, another way to make sure you receive what you want and nothing else is to use the Form Validation library. For example, if you know a method should receive a number as parameter, you can do something like this:
public function product($product_id)
//now you can work with (int) $product_id...
How to handle POST data
In this case, the first line of defence is also inside the configuration file (application/config/config.php).
When dealing with forms, the most common type of attack is the Cross Site Request Forgery. If you don’t have a protection against this type of attack, anyone can at any type emulate filling a form from your site without even being on your site (by simply setting your address as target for the action of the form).
To avoid this type of attack, when displaying a form a site can also create a token that is saved in the session data and as a hidden input value. Once someone is submitting the form, the website verifies if the token inside the hidden input field is the same as the session token and if the two are the same, works with the data.
Fortunately CodeIgniter does this automatically if you let it. In the configuration file you might see the following lines:
| Cross Site Request Forgery
| Enables a CSRF cookie token to be set. When set to TRUE, token will be
| checked on a submitted form. If you are accepting user data, it is strongly
| recommended CSRF protection be enabled.
| 'csrf_token_name' = The token name
| 'csrf_cookie_name' = The cookie name
| 'csrf_expire' = The number in seconds the token should expire.
| 'csrf_regenerate' = Regenerate token on every submission
| 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks
$config['csrf_protection'] = FALSE;
$config['csrf_token_name'] = 'csrf_ciapp_token';
$config['csrf_cookie_name'] = 'csrf_ciapp_name';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;
$config['csrf_exclude_uris'] = array();
So, to enable the CSRF protection, you should set it to TRUE. Once you’ve done this, the CSRF token will be inserted every time you use form_open() function (a function that is served by the Form helper).
Also, you should USE THE FORM VALIDATION LIBRARY (http://www.codeigniter.com/user_guide/libraries/form_validation.html). I can’t stress it enough, when working with forms, always validate the values. If you do this, you are making sure that the data inserted into your forms is prepared and validated.
You can set the rules so that they use the native php function in order to prep the data before validation (http://www.codeigniter.com/user_guide/libraries/form_validation.html#prepping-data).
Also, never and I mean NEVER access the form field by using $_POST[‘field’]. What is the use of form validation if after doing it you are returning to the original values?
Use $this->input->post(‘field’); This is part of the Input class, which filters data coming from outside sources. This method can also receive a second boolean parameter which if set to TRUE will also apply XSS filtering (use it only if you don’t care what the user is sending you and you are a cleaning maniacal bastard).
Using the data filtered by the Input class
Always, ALWAYS use the Input class (http://www.codeigniter.com/user_guide/libraries/input.html) when you retrieve data from external sources (POST, GET, COOKIE, SERVER).
This class is automatically called when a new controller is invoked. See here what it does when the controller is loaded: http://www.codeigniter.com/user_guide/libraries/input.html#security-filtering.
You can also use the input class to retrieve data from GET ($this->input->get(‘some_get_value’);) or from a cookie ($this->input->cookie(‘some_cookie_value’);).
That’s about it. If you find this information somewhat lacking, please do write a comment. I want it to cover the most security related issues. Hope it helped you.