PHP applications have a reputation for higher than average security problems. What configuration techniques do you use for making sure the application is secure as possible?
I'm looking for ideas like:
- Using Hardened PHP/Suhosin
- Using mod_security
- Disabling register_globals and allow_url_fopen in php.ini
I normally use Linux, but feel free to suggest Windows solutions too.
Use the open_basedir directive to confine your PHP scripts to their home directory and eventual extra application directories. This is very efficient by itself.
Use hardened php because that costs nothing and it can help.
Use suPHP to have PHP scripts execute as the owner of the file (one user per website) and avoid using files with bad permissions such as 777... suPHP can also allow you to have on php.ini per website so that one site's stupid requirement don't destroy everything.
Mod_security is a big plus but needs to be well used and configured.
In my experience, most vulnerabilities on a PHP-based web site are the result of poor (site) design, rather than flaws in PHP itself.
Some quick tips:
*You might also take a peek at a short post I wrote called "Securing phpinfo(), sort of" and be sure to read the comments http://egovsergo.com/2009/04/03/protecting-your-phpinfo/ It was a quick idea I had to (somewhat) protect phpinfo() if I somehow forgot to remove it on a production site.
In a more general way, some developers write wrappers for sensitive functions which check whether not the "production site" flag is set or not, and disables the sensitive function in production.
Other parameters that should be altered to harden the PHP:
Store all PHP errors in file /var/log/phperror.log:
I've added the dotdeb repositories to my /etc/apt/sources.lst
As they patch php / apache / mysql much more frequently than Debian does.
Consider setting up
open_basedir
on a "per site" basis.open_basedir
is a php.ini setting which will prevent your scripts from accessing files outside of a defined white list. If your server hosts several sites, it'll prevent one site from reading the database settings from another site. It'll also prevent a php script from accessing/modifying core system files. Open basedir is easy to set up, just add the line "php_admin_value open_basedir /my/list/of/folders:/as/a/colon/seperated/list
" to each Apache vhost.Also consider turning off the PHP script engine for all sites/folders which shouldn't contain PHP scripts (e.g. an uploaded images folder). Again, this is simple, add "php_admin_value engine off" to any Apache VirtualHosts not needing php. To disable PHP in a directory, put the same thing into a Directory tag.
Run file permissions as tight as possible, avoid write access to PHP scripts for the Apache user, this prevents a running script from modifying itself or other scripts on the same site/server. Avoid 777 permissions if at all possible, figure out the minimum permissions required to run the application and use those.
If you're hosting multiple sites, each with their own database, use a seperate MySQL/Postgres user for each, and set permissions on each user such that they only have access to the relevant databases. Again this will prevent a rogue script from tampering with another application's database.
Suosin, HardenedPHP, mod_security and the like are all valuable as well, but use them in addition to a tightly locked down configuration, not instead of.
Suhosin has a rather substantial performance cost, so the "costs nothing" comment is a bit off.
Are you looking for some basic firewall/topology suggestions? I like the idea of using things like pound to prevent access directly to the PHP webserver from the unwashed internets. That way you can also segregate the webserver from other parts of your network as well.
Using Suhosin/mod_security/SuPHP certainly will turn your PHP server secure. Disabling certain functions like exec, passthru, system and escapeshellcmd will help a lot too.