skip to content

Passing Disallowed Characters through the URL in Code Igniter

December 30th, 2006

One of the very nice things about CodeIgniter (and really all the PHP frameworks I've looked at) is the built in security tools. For example, CodeIgniter automatically cleans cookies, sessions, user input and URLs in addition to coming with a host of other built in tools to make your job in securing your application as easy as possible. But, like all good things, there is a trade off. In the case of security, the trade off is convenince. The more secure, the less convenient. Since security isn't really something we can compromise on, clever developers need to find alternate ways of implementing common things. CodeIgniter for example limits the characters that one can use in a URL to letters, numbers, and "~, %, :, _ and -". A good collection sure, but what if you need to pass other characters, such as "(, ), =" or even spaces? Here's how I did it. For a recent project I needed to work with a large pool of legacy data. There was a fixed database schema that I could not change, and I needed the ability to pass search and sort criteria through a URL. OK, except that these criteria needed to include brackets, spaces, square braces, and a few other characters disallowed in Code Igniter. If you investigate config/config.php you'll find the list of disallowed characters.
$config['permitted_uri_chars''a-z 0-9~%.:_-'
I couldn't simply add those characters to this though, as URL encoding proved to mess up thing in unpredictable and difficult to cope with ways (a simple example was chaning spaces into " "). I experimented with url_encode() but it didn't capture everything I needed it to, and even when it did, it was difficult for me to predict and pass all the characters through the disallowed characters expression. My final solution, and one that I'm very happy with, was to use CodeIgniter's native encryption class to hash up everything, and then decode it on the other end. This worked perfectly, and preserved all the strange wild and unpredictable patterns from the legacy data. The only catch was the during the hashing process, the characters "=" and "+" may present themselves, so I edited my permitted characters to include these. Note the order they appear in. The "-" must go at the end, otherwise it gets interpretted as a range delimiter in the same was "a-z" means "a through z" and not "a, the dash and z".
$config['permitted_uri_chars''a-z 0-9~%.:_=+-' 
Now I autoload the encrypt class, and to pass the data in question I use
$this->encrypt->encode('Koch(Zone2)'); 
This gives something like "VxFSbVFjAmpZfwdRVGoBOlQ5DWQAIw==", which I can decode at the other end.

Drawbacks

  • While this works for my project, the data I'm encoding is fairly short (no more then 15 characters). If you needed to encode very large strings, the encoded output could end up getting too big to work with properly.
  • The URL ends up not being pretty or predictable. While in my particular application this is a good thing, I generally like easy to read semantic URLs like site.com/user/dallard rather then site.com/user/AEQBI1RqCHkPdAV...
Note though, just because the string is encoded and encrypted does not absolve you from needed to sanitize the data. Although its extrememly unlikely that a malicious user could craft an encoded string that could exploit your application, it is (in theory at least) possible. So as always, sanitize and sanity check the input.

This entry was made on December 30th, 2006 @ 8:32 and filed into CodeIgniter, How-To.

Comments

Aniruddha wrote on January 03rd, 2007 @ 14:27

Very good information. Thanks for letting us know.The other day I was having problem with passing email address through URI, now I hope that it may solve my problem.

Post a Comment

Sorry, comments are automatically closed after 45 days, or sooner if one entry gets targetted by spammers. Why not contact me directly?