Turning off error reporting is often mentioned as a standard security precaution when switching to a production environment. After all, you don’t want those precious database table and field names out in the open, for sneaky little hobbitses to view. If someone is rummaging through your site, trying to find vulnerabilities, this severely limits the information they have at their disposal.
This of course falls into security-through-obscurity, which isn’t going to fix bad code (see the last section below for more about designing code to fail gracefully). It merely fogs the windows to your infrastructure a little. Hackers sometime search Google for pages that have been indexed with MySQL errors on them. They are like a giant red flags, waving boldly in the wind, that read ‘Possible Vulnerability Here’; While a folded ‘On Vacation!’ note sits atop the webmaster’s chair.
Plus, from a visual rather than a security standpoint, who wants to see a big ol’ nasty MySQL error when something goes wrong?
Alright, you know it’s a good idea already. Your CodeIgniter site is launched or is on the verge of doing so, but how do you turn off the errors? There are three Codeigniter files that need to be modified:
1. Turn off PHP Errors with error_reporting(0)
In the root directory of your CodeIgniter install, there is an index.php file. The first option in there is ‘PHP ERROR REPORTING LEVEL’. Set it to zero:
CodeIgniter version 2.0.1 and above have an environment constant in the index.php file as well. Setting this to “production” will disable all PHP error output. Read more about this on the Codeigniter User Guide page on Security and on Handling Environments.
2. Turn off Database Errors in Config
The PHP errors are off, but any MySQL errors are still going to show. Turn these off in the /config/database.php file. Set the db_debug option to false:
$db['default']['db_debug'] = FALSE;
3. Adjust Error Logging Threshold
The /config/config.php file has a log threshold option. It states “For a live site you’ll usually only enable Errors (1) to be logged otherwise your log files will fill up very fast.”
$config['log_threshold'] = 1;
A Note about Designing Errors and Bad Input to Fail Gracefully
It is good practice to design your functions to withstand user meddling and the occasional malformed link. If the function in your controller requires a parameter, and then queries the database, wrap it in a conditional to make sure the passed parameter is set, and in the right format. If it only takes integers, don’t let the code pass through a non-integer to the point of querying the database where an error might occur.
If you have a controller that is displaying database-driven items that may disappear, a innocent visitor may have come across it from an old link. Why not put in a nice redirect to a helpful landing page (or a helpful 404) ?
A friendly reminder to beginner PHP programmers: $_GET VARIABLES ARE ALSO USER INPUT, AND SHOULD NOT BE TRUSTED. I only mention this because recently I was combing over some code that was assuming that a GET[‘id’] was a number, and it was being used unfiltered and unescaped in a query. This leaves you open for SQL Injection.
Here’s some more reading and the official docs. The first forum link has some example code that illustrates how to fail gracefully in your model, view, and controller: