Hardening PHP on cPanel servers in 10 steps

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.

About the Author: Esteban Borges

Experienced Sr. Linux SysAdmin and Web Technologist, passionate about building tools, automating processes, fixing server issues, troubleshooting, securing and optimizing high traffic websites.

2 Comments

  1. 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

Leave a Reply

Your email address will not be published. Required fields are marked *