We are working on making a wordpress type system from scratch with a templating system and am wondering about security. We hope to have a SaaS model where the user will be on the same server as a few other users, but we hope to also give them the tools to modify their own Views files, which means PHP access. We are using Laravel as the framework. As a long time Dreamhost user, I know you can section the same machine off into multiple environments, but not really sure what they were using to do so.
How can I prevent the execution of commands like eval(), system commands, and limit the users access to fopen (I assume that is mostly through the linux user permissions). I would like to give them direct file access to the Views folder and to develop their own solutions instead of forcing them to go through me, but without jeopardizing too much. If there are mysql considerations beyond separate users, feel free to chime in there as well.
There are several layers that you need to protect.
Some of the hosters incorrectly rely on PHP "protections" like open_basedir, safe_mode (older PHPs), disable_functions etc.
Even PHP does NOT consider them being security features - http://php.net/security-note.php
These can be disabled with any exploit for PHP and then the whole system is doomed, do not do that.
How it should be done
the bottom
- Separate OS-level/system user for each hosted site
- correct permissions (one can't be able to view/edit page of the other one) - also make sure sub-directories have correct permission as they're going to be similar
- separate session files (LOT of webhostings put session files of each PHP-hosted site into the same directory, that's bad bad bad!
Apache finally got it's own module for this - Apache MPM-ITK.
Long story short: picture this as you'd give the user a shell on the machine (under his own uid) - he can't be able to do anything to the other hosted sites.
- different uid/gid
- system permissions
- framworks like SELinux, AppArmor and similar
- grsecurity if you want to be hardcore.. but the system will be harder to maintain.
going up?
You can get more hard-core. The best I've seen is a shared-library for apache (or whatever you use) - that is used when apache is started using LD_PRELOAD
and it implements all the potentially malicious system calls like system()
, execve()
and basically any other call that you find bad.
I haven't seen a good implementation of this out there yet (other than custom ones somewhere) - correct me if I'm wrong.
Make sure to implement a white-list for this as eg. mail() in PHP executes sendmail by default and that won't work anymore.
conslusion
Add classic disable_functions, open_basedir, etc. into global php.ini, add session.save_path to every vhost - put sessions into user directories. Make sure users don't share anything.
Implement underlaying OS-level separation correctly.
Get hardcore with grsec and LD_PRELOAD lib hooking system calls.
Separation, separation, separation .. soon enough systems like Docker will provide LXC-based containers to separate users on kernel level but it's not quite production ready yet (imho).