Web apps are insecure by default, 99% of web developers don’t think in security when they are building their apps, and if we take a look at the lack of server security that most systems have, it’s a completely insecure world from both parts, app and server side.
That’s why on this guide you will learn how o secure/harden a PHP server in 10 steps, even if your web apps are insecure, this will harden your server security a lot. Let’s begin with the Hardening PHP on cPanel guide.
Hardening PHP on cPanel servers in 10 easy steps
1. Enable suPHP
If you are still working with DSO as your PHP handler, dude, move to suPHP now. suPHP allows your server to execute PHP scripts with the permissions of their owners, this means they will run always with the FTP/cPanel username, instead of nobody (Apache, as it happens with DSO).
Advantages of suPHP:
- Run scripts with your own system/cpanel-ftp user.
- No need to use 777 permissions to write file or directories, 755 is enough.
- You can detect attacks and offending scripts way faster than using DSO handler.
Disadvantages of suPHP:
- It’s slower than using DSO.
- Consumes more RAM memory than using DSO.
- Incompatible with eaccelerator.
Enable suPHP from WHM » Service Configuration » Configure PHP and suEXEC, then set suPHP as the handler from the drop down menu. If you don’t see suPHP there, you will have to add it to your server by recompiling Apache. You can do this by running EasyApache from WHM » Software » EasyApache (Apache Update) or from the shell as root running this script: /scripts/easyapache.
2. Disable unwanted custom php.ini files
Forcing your users to use the system’s php.ini file is one of the best ways to stay secure and away from nasty php.ini directives modifications by remote attackers. Disabling custom php.ini files from public_html directories can be done easily, check out this post:
Disable custom user based php.ini files in cPanel
3. Disable dangerous PHP functions
One of the best ways to secure PHP from unwanted attacks is to disable the most common and dangerous functions that most PHP script kiddies use everyday. In order to do this you need to edit your php.ini file.
nano -w /usr/local/lib/php.ini
then search for
allow_url_fopen
and make sure it’s off
allow_url_fopen = Off
This wil prevent poor written scripts from including data from remote URLs.
After that, make sure you also disable other important php functions. Search for “disable_functions” string, and set it as you see below:
disable_functions = "system, system_exec, passthru, shell, shell_exec, exec, popen, pclose, proc_open, proc_nice, proc_terminate, proc_get_status, proc_close, pfsockopen, leak, apache_child_terminate, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid, escapeshellcmd, escapeshellarg, phpinfo"
4. 4) Disable display_errors to avoid showing sensitive information
PHP errors can deveal lot of sensitive information about your applications and web server software, and this can be really useful information for all those who want to attack your server.
In order to prevent this, we will disable all errors from being displayed on your websites. Instead of showing the errors on the screen, we will also turn on error logging, so you can debug your errors from your logs, and not from a public source.
Find this variable inside /usr/local/lib/php.ini and set as you see below:
display_errors = Off log_errors = On
5. Disable enable_dl directive
This time we will disable the enable_dl directive, which is often used to enable or disable the dl() function. The dl() function allows runtime loading of php extensions at runtime, it also opens a way to byppass open_basedir restrictions. If you application doesn’t need it, you should always disable this function.
Edit php.ini file and set:
enable_dl = Off
6. Hide your PHP information
Set expose_php variable to off in order to hide your PHP version from HTTP headers.
Example of an insecure PHP server showing the full software version:
[[email protected] ~]$ curl -I nixcp.com HTTP/1.1 200 OK Date: Mon, 19 Jan 2016 13:42:34 GMT Server: Apache X-Powered-By: PHP/5.4.45 Connection: close Content-Type: text/html
Now, let’s edit your php.ini file and set:
expose_php = Off
Restart http to apply changes:
service httpd restart
Then the PHP version information should be gone from the HTTP headers, example:
[[email protected] ~]$ curl -I nixcp.com HTTP/1.1 200 OK Date: Mon, 19 Jan 2016 13:44:55 GMT Server: Apache Connection: close Content-Type: text/html
7. Install Mod_Security
Mod_Security is one of the best application firewalls for cPanel servers. It will protect you from common threats like SQL injection, XSS attacks, and much more. installing mod_security is pretty much easy and can be done within a few minutes.
Check this out: How to install ModSecurity on cPanel
8. Install Suhosin
Suhosin is a must have when you are securing your PHP servers. It’s a patch against the PHP core and also a PHP extension that protects from known and unknown flaws in PHP applications. If you don’t have Suhosin installed check out this tutorial: How to Install Suhosin on cPanel
9. Upgrade your PHP version
Keep your PHP version updated from the latest releases by running EasyApache from WHM or from the shell at /scripts/easyapache. This will keep attackers away from old PHP version vulnerabilities.
10. Switch to Cloudlinux
Cloudlinux is one of the best security solutions for cPanel based servers. It uses CageFS and SecureLinks technologies to jail users into their own virtualized file systems. This ways attacks to one users will never affect others.
CloudLinux also uses a hardened PHP, which secures old vulnerable versions of PHP.
You can get cloudlinux from their website at Cloudlinux.com
Conclusion
After following this 10 steps to secure your PHP server, your security in web applications should be pretty much robust than before. If you have any other PHP security tip, please let us know so we can add those to this Hardening PHP on cPanel tutorial.
There is an error in the text that you imply we should copy and paste in php.ini
disable_functions = system, system_exec, passthru, shell, shell_exec, exec, popen, pclose, proc_open, proc_nice, proc_terminate, proc_get_status, proc_close, pfsockopen, leak, apache_child_terminate, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid, escapeshellcmd, escapeshellarg, phpinfo4) disable display_errors
At the end of this line it says: phpinfo4) disable display_errors
This should probably be: phpinfo
The rest belongs to the text that follows: 4) disable display_errors
Thanks for reporting this Fred, it has been fixed 😉