Skip to content Skip to navigation

Top 10 PHP Best Security Practices for Sys Admins

November 20, 2012
Top 10 PHP Best Security Practices for Sys Admins

PHP is widely used for various of web development. However, misconfigured server-side scripting would create all sorts of problem. And here are php security best practices that you should aware when configuring PHP securely. Nowadays most of the web servers are operated under Linux environment (like: Ubuntu, Debian...etc). Hence, in the following article, I am going to use list top 10 ways to enhance PHP Security Best Practices under Linux environment.

My sample setup for PHP Security Tips:

DocumentRoot: /var/www/

Default Web server: Apache 

Default PHP configuration file: /etc/php.ini

Default PHP extensions config directory: /etc/php.d/

Our sample php security config file: /etc/php.d/security.ini (you need to create this file using a text editor)

Operating systems: Ubuntu (the instructions should work with any other Linux distributions such as RHEL / CentOS / Fedora or other Unix like operating systems such as OpenBSD/FreeBSD/HP-UX).

1.Reduce built-in PHP modules

To enhance performance and security, it is highly recommended to reduce modules used with PHP. To see what modules that are installed with by executing the following command:

# php -m

And you may get similar result.

[PHP Modules]

apc

bcmath

bz2

calendar

Core

ctype

curl

date

dom

ereg

exif

fileinfo

filter

ftp

gd

gettext

gmp

hash

iconv

imap

json

libxml

mbstring

memcache

mysql

mysqli

openssl

pcntl

pcre

PDO

pdo_mysql

pdo_sqlite

Phar

readline

Reflection

session

shmop

SimpleXML

sockets

SPL

sqlite3

standard

suhosin

tokenizer

wddx

xml

xmlreader

xmlrpc

xmlwriter

xsl

zip

zlib

[Zend Modules]

Suhosin

To remove a module, execute this command. Example: remove sqlite3 module

# rm /etc/php.d/sqlite3.ini

or

# mv /etc/php.d/sqlite3.ini /etc/php.d/sqlite3.disableRestrict

2. Minimize PHP Information Leakage

On default the php would generate a line within the HTTP header (Like: X-Powered-By: PHP/5.2.10) on each response. However, this create a valuable information for attacker on your system information. And a sample HTTP header response as follow:

HTTP/1.1 200 OK

X-Powered-By: PHP/5.2.10

Content-type: text/html; charset=UTF-8

Vary: Accept-Encoding, Cookie

X-Vary-Options: Accept-Encoding;list-contains=gzip,Cookie;string-contains=wikiToken;string-contains=wikiLoggedOut;string-contains=wiki_session

Last-Modified: Thu, 03 Nov 2011 22:32:55 GMT

...

Hence, it is highly recommended to disable PHP information leakage. To disable it, we have to edit  /etc/php.d/secutity.ini and set the following directive:

expose_php=Off

3. Minimize PHP loadable modules

By default, RHEL loads all the extensions modules found in /etc/php.d/ directory. To disable or enable a particular module, just comment out the module name in the configuration file in /etc/php.d/ directory. However, to optimize PHP performance and security, it is highly recommended to enable the extensions when your application requires.  Let take an example: to disable GD extensions, type the following commands:

# cd /etc/php.d/

# mv gd.{ini,disable}

# /etc/init.d/apache2 restart

To enable the GD PHP module, then type the following commands:

# mv gd.{disable,ini}

# /sbin/service httpd restart

4. Log PHP Errors

To enhance our system and web applications security, PHP error message should not be expose to all site visors. To achieve this, go to edit  /etc/php.d/security.ini file and set the following directive:

display_errors=Off

However, to facilitate developer on bug fixing. All of PHP errors should be logged in log files.

log_errors=On

error_log=/var/log/httpd/php_scripts_error.log

5. Disable Remote Code Execution

If Remote Code Execution enabled which allow php code to retrieve data from remote locations, like an FTP or web site by execute PHP build function, like: file_get_contents().

A lot of programmer use these functions to get data from remote location through FTP or HTTP protocols. However, this posts a high vulnerabilities on PHP based application. Since a lot of programmer didn't do proper input filtering when passing user-provided data to these function and open a securiy hole and create code injection vulnerabilities. To fix this issue, disable the allow_url_fopen in /etc/php.d/security.ini and set the following directive:

allow_url_fopen=Off

Other than that, I also recommended to disable allow_url_include to enhance system security:

allow_url_include=Off

6. Disable dangerous PHP functions

PHP have a lot of dangerous built in function which may crack your system if not used properly. And you can set list of PHP built in functions to be disable by edit /etc/php.d/security.ini

disable_functions =exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

7. Control Resource

To enhance system stability, it is highly recommended to set maximum amount of time each script may spend parsing request data and maximum amount of memory a script may consume. Correct configure these parameters can prevent any php script consume too much of resources or memory and lead to system unstable or down.

# set in seconds

max_execution_time =  30

max_input_time = 30

memory_limit = 40M

8. Restrict PHP access to file system

The open_basedir directive which specified the directories that PHP is allowed to access using functions like fopen(). If any script tries to access the files outside the path defined by open_basdir, PHP will refuse to open. It is important to note that you cannot use a symbolic link as a workaround.

; Limits the PHP process from accessing files outside

; of specifically designated directories such as /var/www/html/

open_basedir="/var/www/html/"

; ------------------------------------

; Multiple dirs example

; open_basedir="/home/httpd/vhost/cyberciti.biz/html/:/home/httpd/vhost/nixcraft.com/html/:/home/httpd/vhost/theos.in/html/"

; ------------------------------------

9. Restrict File and Directory Access

Proper security settings:

Make sure your Apache run as a non-root user such as www-data or www. For files and directories under /var/www/ should be owned by non-root user as well. To change owner, execute the following command.

# chown -R apache:apache /var/www/

10. Write protection on Apache, PHP & MySQL configuration files

Use the charrt command to write protect configuration files:

# chattr +i /etc/php.ini

# chattr +i /etc/php.d/*

# chattr +i /etc/my.ini

# chattr +i /etc/httpd/conf/httpd.conf

# chattr +i /etc/

The chattr command can write protect your php file or files in /var/www/html directory too:

# chattr +i /var/www/html/file1.php

# chattr +i /var/www/html/

Taxonomy: