PHP is watching you

I just received an email with the subject Serious Vulnerability in your Blog and my /etc/passwd attached. WTF..?! Well, I've just started my security master, thus I wouldn'd dream of claiming I'm absolutely an expert at all, but however it's kinda reassuring to realize, it's that easy to browse ones filesystem over the net, if there are bugs in your code, even if you're running Apache more or less with its recommended security configuration ...

The Vulnerability

Soon after I learn about how my mate was able to download the /etc/passwd without any permissions. It was rather simple. All he did, was to use the wget command, ignoring the certificate check, since my website is running with ssl only, and request what ever he wanted as follows.

 wget --post-data 'post=/etc/passwd' --no-check-certificate 'https://phgamper.ch'

I tried to download some other files and succeed in getting /etc/fstab but failed in getting /root/hallo.txt. By a closer look at the ACL I mentioned, that the root's home directory is restricted to the owner but not the /etc, i.e.

...
drwxr-xr-x 111 root root       4096 Oct 23 21:29 etc
...
drwx------   8 root root       4096 Oct 24 13:21 root
...

I concluded that the issue must lie somewhere in the PHP code, not least because of the fact, that trying to download from the root's home directory results in PHP throwing a permission denied warning.

<b>Warning</b>:  include(/root/hallo.txt): failed to open stream: Permission denied in <b>/home/phgamper/www/public/index.php</b> on line <b>41</b><br />
<br />
<b>Warning</b>:  include(): Failed opening '/root/fancy.pwd' for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in <b>/home/phgamper/www/public/index.php</b> on line <b>41</b><br />

The Fix

I spent some time in looking at the code and found the following code fragment. Ahead removing it did the trick.

if (isset($_POST['post']))
{
    $include = $_POST['post'];
    unset($_POST['post']);
    include ($include);
}

Well, as I built this blog, I just copied an old project, deleted everything unnecessary, changed some functionalities and added some other features. Thereby I've changed the way of how PHP dynamically includes the content, since it was not that easy to use. Indeed using $_POST directly to load files is a stupid idea at all, but back then, when I've built the old project, I didn't realy care about. Normaly PHP is running on a Webserver, often on Apache, and thus with the webservers priviledge. Since apache is a user on the system, PHP is able to access all files that either belongs to apache, its group or is accessible by nobody.

Lesson learned

Once more the reality have shown, it is hard to write bug free software, and it's not always a good idea to copy old code and modify it to ones needs without worring about...