Disallowed Key Characters in CodeIgniter

If you are a PHP developer doing some projects using the CodeIgniter Framework, chances are you had encountered this error message in a blank page.

“Disallowed Key Characters.”

When you go to the official documentation of CodeIgniter itself, it will say that you might had passed an illegal character in the URL. So what are these characters?

There is a little twist with that question. CodeIgniter uses Regular Expression to determine which characters should be considered invalid. The application/config/config.php says it is:

$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';

But when you look at the actual “code” that does checks the allowed characters, you will see it like this:
_clean_input_keys function of system/core/Input.php

if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
{
   exit('Disallowed Key Characters.');
}

This is commonly the pitfall newbie users of CodeIgniter is falling into, since they expect that the permitted_uri_chars is the parameter that needs to be adjusted when they encountered that error. Which obviously wont work, since the Input class is completely reading different regex expression.

A quick way to solve the problem is by editing the system/core/Input.php itself (or you can override it in your custom library).

Now that you know where to change the list of allowed characters, you can now whitelist the blocked character so that it wont be flagged as invalid. But then, there are occasions wherein you don’t know what is the character being flagged as invalid (for example in a very long url).

What you can do to determine what is the character being flagged as invalid is by modifying the Input.php like this. On the _clean_input_keys function, change it so that:

if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
{
   exit('Disallowed Key Characters.'. $str);
}

By appending the $str variable in the error message, you now have an idea what to whitelist in the regex.

for example, it might be the equal sign “=”

if that is the case, then you can now modify the regex to include the equal sign

if ( ! preg_match("/^[a-z0-9:_\/-=]+$/i", $str))
{
   exit('Disallowed Key Characters.'. $str);
}

The character might vary depending on the output of the error message, so you need to apply it in your own case.