PHP functions to be disabled on shared hosting
Tags: webhosting, security.
By lucb1e on 2012-06-26 01:23:32 +0100
There are plenty of websites giving you advice on which PHP functions to disable in a shared hosting environment. Trying like 15 blogs and websites, all of them got it wrong, including (to my surprise) the Security Stack Exchange**.
I don't know who or when, but someone once posted a list with PHP functions to be disabled and everyone copied it. There are roughly 3 variants on this, which block random functions like mysql_pconnect (but not mysql_connect or sockets themselves), FTP functions, or even string manipulation functions which are obviously totally benign.
Time to set things right.
The functions you should disable
- exec: This runs programs. Upload a binary executable file, optionally chmod +x it for execution permissions, and you can run it.
- system, passthru, pcntl_exec: see exec.
- shell_exec: Also runs programs, but works like any system console.
rm -rf * says enough.
- proc_* functions: Can do stuff like exec() and more.
- popen: Contacts other processes, seems better to disable...
- Some functions which I believe speak for themselves: apache_child_terminate, apache_setenv, define_syslog_variables, posix_kill.
- posix_setpgid, posix_setsid, posix_setuid: Not entirely sure what it does, but it looks like elevating your permissions. Probably impossible with proper settings... but I'm not certain about this, and I can't imagine it what you would need it for in common webapplications anyway.
- openlog: Opens a connection to the system log.
- php_uname: Although not insecure per se, in my opinion people needn't know this.
- syslog: generates a system log message.
- phpinfo: While usually not too big a problem, if an exploit is found somewhere it makes it easy to Google for it. Disabling this won't stop determined hackers/crackers, though.
So in the end, we have in the php.ini:
disable_functions = exec, passthru, shell_exec, system, proc_open, popen, apache_child_terminate, apache_setenv, define_syslog_variables, pcntl_exec, openlog, posix_getpwuid, posix_kill, posix_setpgid, posix_setsid, posix_setuid, posix_setuid, posix_uname, proc_close, proc_get_status, proc_open, proc_terminate, syslog
(Not including phpinfo and php_uname, you can choose to include those yourself if you deem it necessary.)
One very important one though: Don't forget open_basedir!
Forgetting this will compromise the entire security you just tried to add.
You can set this per vhost in Apache like this:
php_admin_value open_basedir "/path/to/documentroot/or/something"
If you use php_value, which is also popular, a client can easily overwrite the restriction via an .htaccess file. You cannot do this with admin values, trying to modify those will turn up an HTTP 500 Internal Server Error. (Trying to overwrite an admin value through php_value in .htaccess won't error, but also won't work.)
And also realize that these restrictions don't yet block access to socket connections, which may be undesirable depending on your server's network topology. If it makes people bypass a firewall between the internet and the server, you should probably also disable sockets (fsockopen(), socket_create(), and perhaps other functions).
What people say you should disable in PHP
- Any list mentioning either "encode", "decode" or "escape" functions like escapeshellcmd: You can completely discard these lists. They're blocking stuff similar to addslashes() and str_replace(), there is no reason to do that (great example why you just shouldn't copy/paste whatever answer the web gives you).
- "phpAds_XmlRpc" does not even exist according to PHP's documentation, yet I've seen it in many different lists.
- ftp_connect: You're not bypassing anything with this function, so this too is totally useless. Moreover, I've not yet seen any list disabling socket connections, by which you can easily circumvent the blocking of any ftp_* function or even the blocking of curl.
- mysql_pconnect: Does pretty much the same as mysql_connect, except it reuses connections to speed things up. No clue why you would want to disable this.
** The Security StackExchange actually provides a more general answer as well, playing it smartly (getting the most votes by far) and telling us how PHP's ini should not be your only security. He is right, I certainly agree, but he doesn't mention a full list of functions to disable, so that answer is kind of useless too (just like the second-highest one who clearly ripped off a list of another website).
I compiled this list based on other web sources, combining and editing them a lot. This does not mean however that this list is complete and should be thoroughly trusted (perhaps until a PHP.net admin confirms it?). Also, as mentioned, PHP's settings shouldn't be your only protection. Security is not something to take lightly with user data at risk. For me a few hours of research suffices, but you might want to hire professionals.