PHP jailing arbitrary code

766 views Asked by At

We have a Java IRC application where users are allowed to execute arbitrary PHP and get the result. Here is one example of what this is used for:

btc: <php>$btc = json_decode(file_get_contents('https://btc-e.com/api/2/1/ticker'), true); $ticker = $btc['ticker']; echo "Current BTC Ticker: High: $".$ticker['high']." Low: $".$ticker['low']." Average: $" . $ticker['avg'];

We also have a python setup, but we like PHP because PHP does not require newlines in the code anywhere. (Because this is IRC, we cannot give it newlines unless we exec a web-loaded .py file)

The issue is how to prevent people from trying to exploit the system, such as in:

<php>echo readfile("/etc/passwd");

Which would, clearly, read out the passwd file for all to see.
We are also having this problem, after we tried to block readfile():

<php>$rf = readfile; echo $rf("/etc/passwd");

How should we go about securing this system? (The full code is on github, for any interested: https://github.com/clone1018/Shocky)

As an aside, no real sensitive information is being exposed, as the whole thing is in a VM, so it isn't a "timebomb" or anything. We still want to lock it down though.

2

There are 2 answers

6
kitti On BEST ANSWER

That sounds like plugging one hole in a colander. Filesystem security should be handled by the OS, not the application. And as far as /etc/passwd goes, the OS is already securing it.

Here's the first line of my /etc/passwd - yes, I'm going to post it publicly:

root:x:0:0:root:/root:/bin/bash

Usually, passwords aren't actually stored in /etc/passwd. User information is, but the passwords are replaced with x, with the real password only available to the root user.

However, you should lock down PHP to some degree. You can change many PHP options during runtime with ini_set, including open_basedir. http://www.php.net/manual/en/ini.core.php#ini.open-basedir

3
APZ On

If you only want to restrict the file reading maybe this can help http://www.php.net/manual/en/ini.core.php#ini.open-basedir

If you are using an old version of php < 5.4 you can consider using php safe mode

http://php.net/manual/en/ini.sect.safe-mode.php

Set the following vars for safe mode to restrict php

safe_mode_exec_dir
disable_functions = readfile,system

and many other

Also the user wont be able to read any file for which uid is different, e.g. /etc/password. Be advised that safe mode is depreciated/ removed from latest versions of php