Wejn s.r.o.

Solving complicated IT problems is our hobby.

Hunting Down the CodeIgniter "Disallowed Key Characters" Error

TL;DR: Google Analytics recently started setting __utmt_~1 cookie that breaks CodeIgniter-based websites; fix is mentioned below (adding one character to one of CI’s files).

Intro

Over the weekend I got a strange assignment from my buddy Michal C. at WebHat hosting. One of our customers complained that we broke their website because it keeps showing “Disallowed Key Characters” intermittently.

The customer further asserted that they did not change anything and thus it must be our [hosting’s] fault.

I set to figure out what’s going on.

Path to resolution

Loading the webpage of that customer I couldn’t reproduce the error (in my default, battle hardened browser). I switched browser to vanilla Firefox… and sure enough, the website broke with “Disallowed Key Characters” when I clicked link from their front page. Same story with Chromium.

Whiskey Tango Foxtrot?

Web-searching for “Disallowed Key Characters” did not get me much closer to figuring out what’s going on. Found some posts about the issue, e.g. this SO thread, but nothing that would shed some light why this issue suddenly surfaced on our customer’s website.

I set to test the customer’s assertion that they did not change anything… and ran couple of diffs between their current website and randomly selected older backups. No change, except for some newly uploaded images.

At this point I thought it’s either something in their SQL DB or it’s somehow browser related (remember, my battle hardened browser worked just fine).

Checked cookies in the vanilla Firefox and one thing stood out:

There’s a cookie named __utmt_~1 that I did not encounter before. I know that Google Analytics sets all kinds of cookies with __utm prefix, but I haven’t seen this tilde-one creature before.

Then it hit me – the reason why my default browser did not choke on it: I have many of the online tracking services blocked, thus the GA cookies don’t get set.

OK, it seems CodeIgniter chokes on cookies with ~ in them.

To test, I removed the cookie. Refreshed the page, everything ok. Refreshed again, ka-boom, same problem.

OK, problem found. Now what?

Fix

The fix is actually straightforward, already mentioned in the abovementioned StackOverflow thread.

This diff explains it best:

1
2
3
4
5
6
7
8
9
10
11
12
13
diff --git a/system/libraries/Input.php b/system/libraries/Input.php
index a36420b..5bce0d0 100644
--- a/system/libraries/Input.php
+++ b/system/libraries/Input.php
@@ -214,7 +214,7 @@ class CI_Input {
        */
        function _clean_input_keys($str)
        {
-               if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
+               if ( ! preg_match("/^[~a-z0-9:_\/-]+$/i", $str))
                {
                        exit('Disallowed Key Characters.');
                }

Basically you add the tilde (~) to the regexp of allowed key characters in the _clean_input_keys method within CodeIgniter’s Input.php file.

It’s that easy. ;)

Of course, you could be more precise than adding tilde to allowed characters. But I’m no CodeIgniter expert and couldn’t see an obvious vulnerability (security or otherwise) in adding the tilde character to allowed chars.

Outro

I hope this post will ease your pain should you trip over the same issue.