PHP security practices that system administrators must be aware of

Source: Internet
Author: User
Tags log log php server php error php source code sql injection attack apache log nginx server csrf attack
PHP security practices that system administrators must know
PHP is an open source server-side scripting language that is widely used. The Apache Web server provides this convenience: access to files and content via HTTP or HTTPS protocol. Improperly configured server-side scripting languages can cause a variety of problems. So be careful when using PHP. Here are 25 best practices for PHP security that your system administrator can use to securely configure PHP.
Sample environments provided for PHP security tips

? file root directory (DocumentRoot):/var/www/html
? Default Web server: Apache (can use LIGHTTPD or nginx instead of Apache)
? default PHP configuration file:/etc/php.ini
? default PHP Load Module configuration directory:/etc/php.d/
? Our sample PHP Security profile:/etc/php.d/security.ini (need to use a text editor to create the file)
? operating system: Rhel/centos/fedora Linux (related instructions should be compatible with any other Linux distributions such as Debian/ubuntu, or other Unix-like operating systems such as Openbsd/freebsd/hp-ux).
? default PHP Server TCP/UDP port: None

When writing code for most of the operations listed in this article, it is assumed that they will be executed by the root user running the bash shell or any other modern shell:
$ php-v
Example output:
PHP 5.3.3 (CLI) (BUILT:OCT 24 2011 08:35:41)
Copyright (c) 1997-2010 the PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
For demonstration purposes, I will use the following operating systems:
$ cat/etc/redhat-release
Example output:
Red Hat Enterprise Linux Server release 6.1 (Santiago)
1th Best Practice: Know your opponent

PHP-based applications face different types of attacks. I have noticed several different types of attacks:

1. XSS: Cross-site scripting is a security vulnerability in a Web PHP application that an attacker can use to steal information from a user. You can configure Apache to write more secure PHP scripts (verify all user input) to avoid XSS attacks.

2. SQL injection attack: This is a security vulnerability in the database layer of the PHP application. When user input is incorrectly filtered, the application can execute any SQL statement. You can configure Apache to write security code (validate and convert all user input) to avoid SQL injection attacks. A common practice in PHP is to use a function called mysql_real_escape_string () to convert a parameter before sending a SQL query.

3. File Upload: It allows visitors to put files on (upload files) to your server. This can lead to a number of security issues, such as deleting your files, deleting databases, and getting user details. You can use PHP to disable file uploads, or to write secure code (such as validating user input, allowing only image file types such as PNG or GIF).

4. Add local and remote files: An attacker can open a file from a remote server and execute any PHP code. This allows them to upload files, delete files, and install backdoors. You can configure PHP to disable the remote file Execution feature.

5. Eval (): evaluates the string as PHP code. Attackers often use this function to hide their code and tools on the server itself. You can configure PHP to disable eval ().

6. Sea-surf Attack (cross-site request forgery, CSRF): This attack forces end users to perform harmful actions against Web applications that currently have their identities verified. If it is an ordinary user, a successful CSRF attack can compromise the end user's data and operations. But if the end-user being targeted uses an administrator account, this can compromise the entire Web application.

2nd Best Practice: Find a built-in PHP module

To view a set of compiled PHP modules, enter the following command:
# php-m

Example output:

[PHP Module]

[Zend Module]

I recommend that you use PHP with a reduced number of modules to enhance performance and security. For example, you can disable the Sqlite3 module by deleting (removing) the configuration file or renaming (or moving) a file named/etc/php.d/sqlite3.ini, as follows:
# Rm/etc/php.d/sqlite3.ini

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

Other compiled modules can only be removed by reinstalling the thin-provisioned PHP. You can download the PHP source code from and compile it as follows to support GD, fastcgi, and MySQL:
./configure--with-libdir=lib64--with-gd--with-mysql--prefix=/usr--exec-prefix=/usr--bindir=/usr/bin--sbindir=/ Usr/sbin--sysconfdir=/etc--datadir=/usr/share--includedir=/usr/include--libexecdir=/usr/libexec--localstatedir =/var--sharedstatedir=/usr/com--mandir=/usr/share/man--infodir=/usr/share/info--cache-file=. /config.cache--with-config-file-path=/etc--WITH-CONFIG-FILE-SCAN-DIR=/ETC/PHP.D--enable-fastcgi-- Enable-force-cgi-redirect

See how to compile php and reinstall on UNIX-like operating systems ( for more information.

3rd best Practice: Restricting the disclosure of PHP information

To limit PHP information disclosure, disable expose_php. To edit the/etc/php.d/secutity.ini, execute the following command:

When Expose_php=off is enabled, expose_php reports to the outside world that PHP is installed on the server, which includes the PHP version (such as x-powered-by:php/5.3.3) inside the HTTP header. The globally unique identifier of the PHP identity (GUID, see example Http:// is also shown, As a result, they are added to the URL of a PHP-enabled Web site and the corresponding identity is displayed. After expose_php is enabled, you can view the PHP version using the following command:

$ curl-i Sample output:

http/1.1 OK
content-type:text/html; Charset=utf-8
Vary:accept-encoding, cookies
x-vary-options:accept-encoding;list-contains=gzip,cookie;string-contains=wikitoken;string-contains= Wikiloggedout;string-contains=wiki_session
Last-modified:thu, Geneva 22:32:55 GMT
... I also recommend that you perform servertokens and Serversignature commands in httpd.conf to hide the Apache version and other information ( rhel-centos-hide-httpd-version/).

4th best Practice: Minimize loadable PHP modules (dynamic load modules)

PHP supports dynamic load module (Extensions). By default, Rhel loads all the load modules in the/etc/php.d/directory. To enable or disable a module, simply locate the configuration file in the/etc/php.d/directory and add a comment to the module name. You can also rename or delete the module configuration file. For best PHP performance and security, you should only enable the load modules required by the Web application. For example, to disable the GD load module, enter the following command:

# cd/etc/php.d/
# MV Gd.{ini,disable}
#/sbin/service httpd Restart to enable the PHP module named GD, enter:

# MV Gd.{disable,ini}
#/sbin/service httpd Restart

5th best Practice: Write all PHP errors into the log

Don't let PHP error messages be exposed to all visitors to the site. To edit the/etc/php.d/security.ini, execute the following command:

Display_errors=off Make sure that you log all PHP errors into the journal file (

Error_log=/var/log/httpd/php_scripts_error.log 6th Best Practice: Do not allow uploading of files

For security reasons, edit/etc/php.d/security.ini and execute the following command:

File_uploads=off If the user who uses your application needs to upload the file, just set Upload_max_filesize ( linux-unix-apache-increase-php-upload-limit/), you can enable this feature, which limits the maximum number of files that PHP allows to upload:

file_uploads=on# files uploaded by php user up to 1MB Max

upload_max_filesize=1m 7th Best Practice: Turn off remote code execution

If enabled, Allow_url_fopen allows PHP's file functions-such as file_get_contents (), include statements, and require statements-to fetch data from remote locations, such as FTP or Web sites.

The Allow_url_fopen option allows PHP's file functions-such as file_get_contents (), include statements, and require statements-to obtain data from remote locations using FTP or HTTP protocols. Programmers often forget that, when transmitting user-supplied data to these functions, there is no proper input filtering, which leaves a hidden danger to code injection security vulnerabilities. Many of the code injection security vulnerabilities that exist in PHP-based Web applications are caused by the combination of enabling allow_url_fopen and bad input filtering. To edit the/etc/php.d/security.ini, execute the following command:

Allow_url_fopen=off for security reasons, I also recommend disabling Allow_url_include:


8th Best Practice: Enable SQL security mode

To edit the/etc/php.d/security.ini, execute the following command:

Sql.safe_mode=on if enabled, mysql_connect () and mysql_pconnect () ignore any variables that are passed to them. Please note: You may have to make some changes to your code. Third-party open source applications (such as workdpress) and other applications may not work at all when Sql.safe_mode is enabled. I also recommend that you turn off MAGIC_QUOTES_GPC ( for all installed PHP 5.3.x because its filtering is not effective or reliable. Mysql_escape_string () and custom filter functions can play a better role (thanks to Eric Hansen, Https://

Magic_quotes_gpc=off 9th Best Practice: Controlling the size of a POST request

As part of the request, the HTTP POST request method is used when the client (browser or user) needs to send data to the Apache Web server, such as uploading a file or submitting a completed form. An attacker could attempt to send too large a POST request and consume your system resources heavily. You can limit the maximum size of the POST request that PHP will handle. To edit/etc/php.d/security.ini, execute the following command:

; Set the actual possible values here

post_max_size=1k1k sets the maximum size of the POST request data allowed by the PHP application. This setting also affects file uploads. To upload a bulk file, this value must be greater than upload_max_filesize. I also recommend that you restrict the methods available to use the Apache Web server. Edit httpd.conf to perform the following directives for the file root directory/var/www/html:

Order Allow,deny
# # Here you can add the rest of the configuration ... # #

10th Best Practice: Resource Control (Denial of service control)

You can set the maximum execution time for each PHP script, in seconds. Another recommended option is to set the maximum amount of time each script might use to parse the request data, and how much memory the script might consume. To edit/etc/php.d/security.ini, execute the following command:

# set, in seconds

Max_execution_time = 30
Max_input_time = 30
Memory_limit = 40M 11th best Practice: Install Suhosin Advanced Protection system for PHP

From the Suhosin Project webpage (

The Suhosin is an advanced protection system for installation-oriented PHP. It is designed to protect servers and users from known flaws and unknown flaws in PHP applications and PHP cores. The Suhosin is divided into two separate sections, which can be used alone or in combination. The first part is a small patch for PHP core, implemented a few low-level protection measures to prevent buffer overflow or format string security vulnerability; The second part is a powerful PHP loading module that implements all the other protections.

See how to install and configure Suhosin ( under the Linux operating system.

12th Best Practice: Disable dangerous PHP functions

PHP has many functions, and if used improperly, they can be used to break into your server. You can use the Disable_functions command to disable a series of functions in/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

13th Best Practice: PHP fastcgi/cgi-cgi.force_redirect Command

PHP works in conjunction with FASTCGI. FASCGI reduces the memory resources consumed by the Web server, but still provides you with the speed and functionality of the entire PHP language. You can configure apache2+php+fastcgi or CGI, as described here. Configuration Command Cgi.force_redirect can prevent anyone from using an address such as to call PHP directly. For security reasons, Cgi.force_redirect should be enabled. To edit/etc/php.d/security.ini, execute the following command:

; For security reasons, in a typical *apache+php-cgi/fastcgi* environment, enable Cgi.force_redirect

Cgi.force_redirect=on 14th Best Practice: PHP user and user group ID

MOD_FASTCGI is a CGI module for the Apache Web server. It can be connected to an external fastcgi server. You want to make sure that PHP is running as a non-root directory user. If PHP is running as a root or under 100 uid, it can access and/or process system files. You must use Apache's suEXEC or mod_suphp to execute PHP CGI as a non-privileged user. The suEXEC feature allows Apache users to run CGI programs with a user ID that is different from the user ID that invokes the Web server. In this example, my php-cgi runs as a phpcgi user, Apache runs as an Apache user:

# PS aux | grep php-cgi Sample output:

phpcgi 6012 0.0 0.4 225036 60140? S Nov22 0:12/usr/bin/php-cgi
phpcgi 6054 0.0 0.5 229928 62820? S Nov22 0:11/usr/bin/php-cgi
phpcgi 6055 0.1 0.4 224944 53260? S Nov22 0:18/usr/bin/php-cgi
phpcgi 6085 0.0 0.4 224680 56948? S Nov22 0:11/usr/bin/php-cgi
phpcgi 6103 0.0 0.4 224564 57956? S Nov22 0:11/usr/bin/php-cgi
phpcgi 6815 0.4 0.5 228556 61220? S 00:52 0:19/usr/bin/php-cgi
PHPCGI 6821 0.3 0.5 228008 61252? S 00:55 0:12/usr/bin/php-cgi
PHPCGI 6823 0.3 0.4 225536 58536? S 00:57 0:13/usr/bin/php-cgi You can use tools such as spawn-fcgi to create remote and local phpcgi processes by phpcgi the user's identity (adding fastcgi users to the system first):

# spawn-fcgi-a 9000-u phpcgi-g phpcgi-f/usr/bin/php-cgi Now you can configure Apache, LIGHTTPD, and Nginx Web servers to use in 127.0.0. 1 The PHP FastCGI that is running on port 9000 at the IP address.

15th best Practice: Restricting PHP access to the file system

The Open_basedir command sets the files that allow PHP to access which directories using fopen () and other functions. If the file is outside the path defined by Open_basdir, PHP refuses to open the file. You cannot use symbolic links as workarounds. For example, only access to the/var/www/html directory is allowed, and access to the/VAR/WWW,/tmp, or/etc directories is not allowed:

Restrict PHP process access to files outside of specially specified directories such as/var/www/html/

; 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/"
; ------------------------------------16th Best Practice: Session Path

Session support in PHP includes a way to preserve some data in subsequent accesses. This allows you to develop more customized applications and increase the attractiveness of your website. The path is defined in the/etc/php.ini file, and all data related to a session is stored in a file in the directory specified by the Session.save_path option. Under Rhel/centos/fedora Linux, the default path is as follows:

Session.save_path= "/var/lib/php/session"; sets the temporary directory where files are stored when uploading files

Upload_tmp_dir= "/var/lib/php/session" ensures that the path is outside/var/www/html and cannot be read or written by any other system user:

# ls-z/var/lib/php/Sample output:

DRWXRWX---. Root Apache system_u:object_r:httpd_var_run_t:s0 Session Note: the-z option of the LS command shows the SELinux security context, such as the file module, user, user group, security context, and file name.

17th Best Practice: Keep PHP, software, and operating system versions up-to-date

Hitting security patches is an important part of maintaining Linux, Apache, PHP, and MySQL servers. You should use any of the following tools (if you are installing PHP through the Package Manager), check all of the PHP security updates as soon as possible and hit them as soon as possible:

# Yum Update or

# apt-get Update && apt-get upgrade You can configure Red Hat/centos/fedora Linux to send Yum package update notifications via email. Another option is to hit all security updates with the Cron job (scheduled Task). Under Debian/ubuntu Linux, you can use Apticron to send security notifications.

Note: Visit frequently ( to find the latest version of source code installation.

18th Best Practice: Restricting file and Directory Access

Make sure that you run Apache as a non-root user such as Apache or www. All files and directories should be owned by non-root users (or Apache users) and placed under/var/www/html:

# Chown-r apache:apache/var/www/html//var/www/html/is a subdirectory, which is a file root directory that other users can modify, because the root directory never executes any files there, nor does it create files there.

Make sure that the file permissions are set to 0444 (read-only) under/var/www/html/:

# Chmod-r 0444/var/www/html/Make sure that under/var/www/html/, all directory permissions are set to 0445:

# find/var/www/html/-type d-print0 | Xargs-0-I {} chmod 0445 {} Supplements for setting appropriate file permissions

The Chown and chmod commands ensure that files in the root directory or file root directory can be written by the Web server user Apache, regardless of the circumstances. Please note: You need to set the most reasonable permission for the development model of your website, so you can adjust the chown and chmod commands according to your own needs. In this example, the Apache server runs as an Apache user. This can be configured in your httpd.conf file with the user and group commands. Apache users need read access to all content in the root directory of the file, but should not have write access rights.

Make sure that httpd.conf has the following command to implement the restrictive configuration:

Options None
AllowOverride None
Order Allow,deny
You should grant write access only when you need it. Some Web applications, such as WordPress, and other applications may need to cache directories. You can grant access to the buffer directory by using the following command:

# chmod A+w/var/www/html/blog/wp-content/cache
# # # block access to all # # #
# echo ' Deny from all ' >/var/www/html/blog/wp-content/cache/.htaccess 19th Best Practice: Write-protect Apache, PHP, and MySQL configuration files

Use the chattr command to write the protection configuration file:

# 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/chattr command can also write to protect a PHP file or multiple files in the/var/www/html directory:

# chattr +i/var/www/html/file1.php
# chattr +i/var/www/html/20th Best Practice: Using a Linux secure load module (such as SELinux)

Linux comes with a variety of security patches that can be used to protect server programs that are improperly configured or compromised. If possible, use SELinux and other Linux security loading modules to restrict your network and other programs. For example, SELinux provides a number of security policies for the Linux kernel and Apache Web servers. To list all Apache SELinux protection variables, please enter:

# Getsebool-a | grep httpd Sample output:

Httpd_use_nfs-Off to disable Apache CGI support, enter:

# setsebool-p httpd_enable_cgi off See Red Hat SELinux Guide ( /security-enhanced_linux/index.html), you can learn more.

21st Best Practice: Installation of mod_security

Modsecurity is an open source intrusion detection and prevention engine that protects Web applications. You can easily install mod_security under Linux to protect Apache and PHP-based applications from XSS and various other attacks:

# #几个实例 # #
#不允许打开 files in/etc/


Secfilter "Delete[[:space:]]+from"
Secfilter "Select.+from" 22nd Best Practice: Run apache/php as much as possible in a chroot jail environment

placing PHP and/or Apache in the Chroot jail environment minimizes the damage caused by potential intrusion events, because it isolates the Web server to a fraction of the file system. You can use the traditional chroot jail environment that comes with Apache. However, it is recommended to use FreeBSD jail, Xen virtualization with container concepts, KVM Virtualization, or OpenVZ virtualization.

23rd Best Practice: Restricting outbound connections using firewalls

Attackers will use tools such as wget to download files locally to your Web server. You can use Iptables to block Apache users from outbound connections. The Ipt_owner module attempts to compare the characteristics of a locally created packet with the creator of the packet. It only works in the output chain. In this example, the Vivek user is allowed to connect to the outside world using port 80 (this applies to Customer portal or CentOS repo access).

/sbin/iptables-a output-o eth0-m owner--uid-owner vivek-p TCP--dport 80-m State--state New,established-j Accept below is another example that blocks all outbound connections from Apache users (except outbound connections to our own SMTP servers), and the Spam Authentication API service:

# ....
/sbin/iptables--new-chain Apache_user
/sbin/iptables--append output-m State--state established,related-j ACCEPT
/sbin/iptables--append output-m owner--uid-owner apache-j apache_user
# allow Apache user to Connec to our SMTP server
/sbin/iptables--append apache_user-p tcp--syn-d 25-j RETURN
# allow Apache user to Connec to API server for spam validation
/sbin/iptables--append apache_user-p tcp--syn-d 80-j RETURN
/sbin/iptables--append apache_user-p tcp--syn-d 80-j RETURN
/sbin/iptables--append apache_user-p tcp--syn-d 80-j RETURN
/sbin/iptables--append apache_user-p tcp--syn-d 80-j RETURN
# # ADD More rules here # #
# No Editing below
# Drop everything for Apache outgoing connection
/sbin/iptables--append apache_user-j reject 24th best Practice: Follow logs and review

Check Apache log files:

# tail-f/var/log/httpd/error_log
# grep ' login.php '/var/log/httpd/error_log
# egrep-i "Denied|error|warn"/var/log/httpd/error_log check php log file:

# tail-f/var/log/httpd/php_scripts_error.log
# grep "... etc/passwd" the/var/log/httpd/php_scripts_error.log log file gives you an idea of what is being attacked by the server and allows you to check that the necessary levels of security have been put in place. AUDITD services are provided for system review. With this service enabled, you can review SELinux events, validation events, file modifications, account modifications, and so on. I also recommend using the standard Linux system Monitoring tool ( to monitor your Web server.

25th Best Practice: Run a service according to a system or virtual machine instance

For large systems installed, it is recommended that you run databases, static content, and dynamic content with different servers.

(Figure 1: Running a service on a different server)

Run different network services on different server or virtual machine instances. This limits the number of other services that may be compromised. For example, if an attacker succeeds in exploiting the vulnerabilities of software such as Apache flow, it can access the entire server, including other services running on the same server (such as MySQL and e-mail services, etc.). However, in the above example, different content is provided as follows:

1. Use LIGHTTPD or Nginx server to provide static assets such as Js/css/images.

2. and Web servers, PHP is used to generate dynamic content.

3. the database server.

4. The server is a very fast cache system for MySQL. It uses the Libevent or Epoll (Linux runtime Environment) to scale to any number of open connections and uses non-blocking network input/output.

5. LB01: The Nginx Web server and the reverse proxy server that are placed in front of the Apache Web server. All connections from the Internet to one of the Web servers are routed through the Nginx proxy server, which can process the request itself or transfer all or part of the request to the primary Web server. The LB01 provides a simple load-balancing mechanism.
26th Best Practice: Other tools

From the Phpids Project webpage (

Phpids (PHP Intrusion Detection System) is a security layer for PHP-based Web applications, with the advantages of simple use, good structure, fast operation and advanced technology. IDS cannot purge, cleanse, or filter any malicious input, only to identify when an attacker attempts to break into your site, and to take the steps that you want it to take.

You can use Phpids to detect malicious users and log any attacks detected to facilitate later analysis. Please note: I have not used this tool personally.

From the Phpsecinfo Project webpage (

Phpsecinfo provides a mechanism that corresponds to the phpinfo () function to report security information about the PHP environment and to provide recommendations for improvement. It is not a substitute for security development techniques or any kind of code or application review, but it is a practical tool in a multi-layered security scenario.

Figure 2: Security information about the PHP application

See Linux Security Essentials ( to reduce the number of attack paths your system faces.

About PHP back-door additions

You may have encountered PHP scripts or so-called common backdoors, such as C99, C99madshell, and r57. The backdoor php script is actually a hidden script that is used to bypass all authentication mechanisms and access your server as needed. The attacker installs it to access your server while attempting to not be discovered. Misuse of a PHP script (or any other CGI script) typically allows you to add code that drills a security hole in a Web browser. Attackers can use this exploited security vulnerability to upload backdoor shells, allowing attackers to gain many features, such as:

? Download the file
? Uploading files
? Installing a Rootkit
? Setting up a junk mail server/relay server
? Set up a proxy server to hide your whereabouts
? control server
? Controlling the database server
? Steal all information
? Delete all information and databases
Open TCP/UDP port and more ports

Important: How do I find the PHP backdoor?

You can use the Unix/linux grep command to search for a C99 or r57 shell:

# grep-ir ' C99 '/var/www/html/
# grep-ir ' r57 '/var/www/html/
# find/var/www/html/-name \*.php-type f-print0 | xargs-0 grep C99
# GREP-RPN "(passthru|shell_exec|system|base64_decode|fopen|fclose|eval)"/var/www/html/concluding remarks

Your PHP-based server is now properly hardened and ready to display dynamic Web pages. However, security breaches are primarily due to failure to comply with best-practice programming rules. To meet the security requirements of Web applications, you should consult more resources, especially PHP programming knowledge, even though this is beyond the scope of the system administrator's work.

Original address:

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.