There are a lot of things wrong with PHP, but it remains a very easy and convenient scripting language that I like to use for both websites and scripts. Webhosts however are reluctant to upgrade their PHP versions to 5.4.0 or newer. Those who already did, will have seen a spike in old PHP code getting owned through SQL injection. Default versions prior to 5.4.0 had safemode as well as "magic quotes" turned on, which allowed newbies to write code that would inherently be hardened against SQL injection. However, at some point, people forgot (how) to sanitize input. It was a convenience thing, that wouldn't stop a determined hacker anyway ... But now that feature is gone (though I'd refer to it as a bug), and we're left with a mess of vulnerable scripts.
On shared hosting, an SQLi vulnerability on one site could mean the compromise of all the websites hosted on that same server. Even though solutions exist like mod_security, I'd like to know how we can limit the impact of a compromise after a successful attempt. How can a webhost sleep peacefully, knowing that no other customers will be affected when just one customer has a security vulnerability.
Just a couple of thoughts, all hypothetically:
We have the choice between creating a new UNIX user for each website, or creating a new UNIX user for each customer, and possibly giving them the same group. Both scenarios come with some advantages and disadvantages. A new system user for each website means privilege separation, enhanced security. A system user per customer who has multiple websites under his account, means a possible compromise of all of those websites when one of the websites is flawed.
We can use grsec to restrict users from accessing files that aren't in their home-directory (much like PHP safemode does).
As I offer IRC shell hosting, my customers require an IP per individual IRC server (I'll have to discuss RFC1459 in a different post, cause I'm a bit disgruntled about that too). Since giving each customer their own VPS isn't exactly profitable, we allow up to eight of them to be grouped together. (More is usually a bad idea: unlike web servers, IRC servers get often visited by packeters. For all of those having a Cisco router, PLEASE secure your SNMP settings...).
Using grsec we can bind every user to their own public IP (for both incoming and outgoing connections). They will not be able to connect from/bind to a public IP that they do not own. Grsec also prevents the users from seeing processes that they don't own (among other awesome things).
I run PHP with PHP-FPM as CGI (which became part of the core, yay!). The scripts are currently ran as the owner of the file (like with suphp/suexec) rather than the www-data user. When a website gets compromised, hackers might be able to get database details of other websites homed on the same server. Now what if ... we could actually make use of our 127.0.0.0/8 subnet and bind each user to such private IP. We then modify the permissions in the MySQL server to only allow access to the customer's database from the customer's own IP. That way, a hacker can't authenticate even if he manages to get the password by a directory traversal attack. This would require the PHP script to run under suexec/suphp. If grsec isn't available to bind the customer to his own IP, we can still hack our way around that via the LD_PRELOAD/LD_LIBRARY_PATH trick (though this isn't safe).
I like this idea. Private IP per customer. MySQL database permissions based on local IP. Why hasn't this been done already? Am I missing something obvious?