I received an email this morning saying that KFM has a security hole – if a user creates a file named “test.php.” (note the ‘.’ at the end), then it is run as if it was “test.php”, even if you explicitly banned the .php extension in your settings.
I immediately added a line of code to ban all filenames which end in ‘.’, released a new version of 1.3 (available on the front page of the site) and corrected 1.4 in SVN.
After thinking about it, I realised that the security problem is not as serious as it may seem (for KFM – not in general). It’s definitely a problem, but in order to use it, you need to have access to a KFM instance in the first place. As securing KFM is not difficult, I think the problem may be contained.
But I digress – this appears to be a problem in Apache. To test it, I checked if renaming a Perl CGI file from .cgi to .cgi. would work, and it did.
This is a little disturbing, as it does not appear to be documented anywhere, so there is no way that a developer would know to avoid this security hole.
So, if you write programs that allow your users to upload or rename files online, make sure that the filename does not have a ‘.’ at the end!
edit: OMG! I was reading the Apache source to try spot the problem, and found the area where it happens – it’s in the file “http/mod_mime.c”. The function “find_ct()” extracts the extension for the server to use. Unfortunately, it ignores all extensions it does not understand, so it’s not just a case of “test.php.” being parsed as ‘.php’, but also “test.php.fdabsfgdsahfj” and other similar rubbish files! This is a serious problem.
There are a number of solutions to this:
- Possibly the correct solution: Keep your downloadables outside the web-accessible area and force the download through a PHP script. Doesn’t matter what extension the file has then.
- Tricky but easier to make portable: Write your own extension identifier using the httpd source as a guide, so you know what Apache will identify the file as (annoyingly complex, possibly, but I’ll need to do it…)
- Easiest, but most annoying for users: Only allow one ‘.’ per filename.
- More difficult, but possibly also correct: Convince Apache that this needs to be fixed, then upgrade immediately when the fix is available.
further update: An easy solution. This problem rears its head when PHP is identified in your httpd.conf using this:
AddHandler php5-script .php
the solution is to change the above to specify the extension must be at the end.
<FilesMatch \.php$> SetHandler php5-script </FilesMatch>