I’m building a teaching tool web app that lets users submit php classes as text and then the app will run them. I think Runkit_Sandbox is the tool for this job, but the docs don’t offer much advice as to which configurations to use.
Is there an established list of functions that should be disabled? Or classes? I’m planning to set all the other configurations to be as restrictive as possible (for example turning off url fopen) but I’m not even 100% sure which those are. Any advice is much appreciated.
I’m building a teaching tool web app that lets users submit php classes
If you are building an app, then you are not assuming too much control on your environment. This means that your solution must be PHP based (which makes Runkit attractive), as the app might be hosted anywhere, possibly somewhere you can't install any of the solutions below. You're still limited to those ISPs that provide Runkit or the possibility to install it, but there's more of them than ISPs amenable to letting you install a chroot jail or a second copy of a web server.
But from the other comments it seems to me that you're building an installation. That is, a whole machine (real or virtual) where you can do as you wish. Which makes other, IMHO more efficient, methods possible:
Install a second web server listening on local host only, with reduced privileges (e.g. running as user nobody with no write access to its own web root). Install a hardened PHP instance there. To do that, start from the old rules with list of functions to disable, then check out HOWTOs and some of the pointers here. This last is more targeted to your customers, but might be useful (and knowing you've thought about security will perhaps cut down on circumventing attempts).
You can even install XDebug on the secondary PHP, and use e.g. PHPUnit's code coverage tools to produce useful information.
Now you can deploy your code by writing to /var/www-secure/website-user123/htdocs
from your primary Web install, which can write to /var/www-secure
, as well as run restart
on the secondary web server via system("sudo...")
commands. You can supply "real life" commands to the hosted web app through curl
.
Linux allows further strengthening using apparmor
/SELinux
, or userid-based firewall rules. This means that whatever the hosted app does, it won't be able to communicate outside, receive other commands than yours, or do anything outside the web root -- where you can read anything and check it, e.g. via tripwire
.
You might even leave the dangerous function enabled (but blocked by apparmor/iptables) and then inspect the logs to see whether the defenses have been triggered. Not really recommended. You do want to check the logs (and heck, maybe run a tripwire check on the system after running an unknown class), however, in case someone succeeded in overthrowing the first layer of defense in the PHP.INI and got smashed by apparmor.
This is hanshenrik's answer, and is attractive if you run things through the CLI. Depending on your setup and what the classes need to do, it can be better than both other alternatives (still requires firewalling/apparmor, or at least it could benefit from them), or less powerful.
As above, but this time the "second install" is completely isolated inside a VM. You can probably do this with Docker but it would not be as secure; still, check this out. You send the code inside the VM using FTP (PHP has commands for this). This setup allows better isolation from the main installation. It is less flexible than the other two solutions, as you should really use one VM for each user, and resetting the VM to neutral is more expensive. Running the VM is more expensive. On the other hand, it can be more thorough (i.e. you can redeploy the whole thing more easily) and limit-smashing attacks are impossible, as the rogue class can at most succeed in hogging the virtual CPU.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With