25 PHP security practices for system administrators and php for System Administrators
PHP is a widely used open source server scripting language. Through HTTP or HTTPS, Apache Web Service allows users to access files or content. Incorrect configuration of the script language on the server may cause various problems. Therefore, PHP should be used with caution. The following are 25 practices for security configuration of PHP for the system administrator.
Example of PHP settings below
- DocumentRoot:/var/www/html
- Default Web service: Apache (can be replaced by Lighttpd or Nginx)
- Default PHP configuration file:/etc/php. ini
- Default PHP Extensions configuration Directory:/etc/php. d/
- PHP security configuration sample file:/etc/php. d/security. ini (this file needs to be created using a text editor)
- Operating System: RHEL/CentOS/Fedora Linux (commands should be available in all other Linux releases, such as Debian/Ubuntu or Unix-like operating systems, such as OpenBSD/FreeBSD/normal operation under the HP-UX)
- Default TCP/UDP port of the PHP service: none
Most of the operations listed in the afternoon are based on the assumption that the root user can perform operations in bash or other modern shell.
$ php -v
Sample 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
The operating system used in this article
$ cat /etc/redhat-release
Sample output
Red Hat Enterprise Linux Server release 6.1 (Santiago)
#1: zhibi
PHP-based applications face various attacks:
- XSS: For PHP Web applications, cross-site scripting is a vulnerable point. Attackers can exploit this vulnerability to steal user information. You can configure Apache or write safer PHP code (verify all user input) to prevent XSS attacks.
- SQL Injection: This is a vulnerable attack point at the database layer in PHP applications. The defense method is the same as above. A common method is to use mysql_real_escape_string () to escape the parameters and then perform SQL queries.
- File Upload: it allows visitors to put (upload) files on the server. This may cause a series of problems, such as deleting server files, databases, and getting user information. You can use PHP to disable file upload or write safer Code (for example, to test user input, only png and gif images can be uploaded)
- Contains local and remote files: attackers can enable remote servers to open files, run any PHP code, upload or delete files, and install backdoors. You can prevent Remote File Execution by canceling the settings.
- Eval (): this function can execute a string like PHP code. It is usually used by attackers to hide code and tools on the server. By configuring PHP and canceling eval () function calls
- Sea-surt Attack (Cross-site request forgery, CSRF. Cross-Site Request Forgery): This attack causes end users to execute unspecified behaviors under the current account. This will endanger the data and Operation Security of end users. If the target end user's account is used for administrator permissions, the entire Web application will be threatened.
#2: Reduce the number of built-in PHP modules
Run the following command to view the module compiled by PHP.
$ php -m
Sample output:
[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
From the perspective of performance and security, I suggest using PHP to reduce unnecessary modules. For example, the above sqlite3 is unnecessary. You can delete or rename the/etc/php. d/sqlite3.ini file to cancel it:
# rm /etc/php.d/sqlite3.ini
Or
# mv /etc/php.d/sqlite3.ini /etc/php.d/sqlite3.disable
Some modules can only be removed by re-Compiling and installing PHP. For example, after you download the PHP source code from php.net, use the following command to compile 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
For more information, see: how to compile and reinstall php on Unix like operating system
#3: Prevent PHP Information Leakage
You can disable export_php to restrict PHP information leakage. Edit/etc/php. d/security. ini as follows:
expose_php=Off
Expose_php will add the PHP information including the version to the server in the HTTP Header (for example, X-Powered-By: PHP/5.3.3 ). At the same time, the global unified identifier of PHP will be exposed. If export_php is enabled, run the following command to view the PHP version:
$ curl -I http://www.cyberciti.biz/index.php
Sample output:
HTTP/1.1 200 OK X-Powered-By: PHP/5.3.3 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 ...
We recommend that you hide Apache versions and other information: ServerTokens and ServerSignature directives in httpd. conf to hide Apache version.
#4: Minimize the load-able PHP module (dynamic Extension)
PHP supports "Dynamic Extensions ". By default, RHEL loads all Extension modules in the/etc/php. d/directory. To enable or cancel a module, you only need to comment out the configuration file in the/etc/php. d/directory. You can also delete or rename the configuration file of this module. To optimize the performance and security of PHP, only the Extension required for Web applications should be enabled. For example, run the following command to cancel the GD module:
# cd /etc/php.d/ # mv gd.{ini,disable} # <span># mv gd.{disable,ini} # <span>display_errors=Off
Make sure to record all error information to the log file
log_errors=Onerror_log=/var/log/httpd/php_scripts_error.log
#6: Prohibit File Upload
For security consideration, edit/etc/php. d/security. ini to cancel file upload.
file_uploads=Off
If you do need to upload a file, enable it and limit the maximum file size accepted by PHP:
file_uploads=On# user can only upload upto 1MB via phpupload_max_filesize=1M
#7: Disable Remote Code Execution
If this feature is enabled, PHP can obtain remote data such as FTP or webpage content in file_get_contents (), include, and require through allow_url_fopen. Programmers often forget to filter user input. If these functions call the data, the injection vulnerability is formed. In PHP-based Web applications, a large number of injection vulnerabilities in code are generated. You can disable this feature by editing/etc/php. d/security. ini:
allow_url_fopen=Off
In addition, we recommend that you cancel allow_url_include:
allow_url_include=Off
#8: enable SQL Security Mode
Modify/etc/php. d/security. ini as follows:
sql.safe_mode=On
When this feature is enabled, mysql_connect () and mysql_pconnect () Ignore all input parameters. At the same time, you need to modify the code accordingly. Third parties and open-source applications, such as Wordpress, may not work properly in SQL. safe_mode. We recommend that you disable magic_quotes_gpc Filtering for PHP 5.3.x because it is simple and inefficient. It is better to use mysql_escape_string () and custom filter functions.
magic_quotes_gpc=Off
#9: control the size of POST Data
Http post is usually part of a request and is used by the client to send data to the Apache Web server, such as uploading a file or submitting a form. Attackers will try to send large POST requests to consume server resources. Edit/etc/php. d/security. ini to limit the maximum size of POST:
Set a reliable value post_max_size = 1 K
The maximum size of 1 K is set here. This setting affects file upload. To upload a large file, the value must be greater than update_max_filesize.
We recommend that you restrict available request methods in Apache. Edit httpd. conf as follows:
<Directory /var/www/html> <LimitExcept GET POST> Order allow,deny </LimitExcept> ## Add rest of the config goes here... ## </Directory>
#10: resource control (DoS Control)
Set the maximum running time for each PHP script. In addition, we recommend that you limit the maximum time used to process request data and the maximum number of available memory.
# Unit: seconds
max_execution_time = 30max_input_time = 30memory_limit = 40M
#11: Install the Suhosin advanced protection system for PHP
For more information, see Suhosin project page: project page.
#12: remove dangerous PHP Functions
PHP has a large number of functions that can be used to intrude into the server. Improper use will become a vulnerability. Cancel these functions as follows:
disable_functions =exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
#13: PHP Fastcgi/CGI-cgi. force_redirect Management
PHP can work with Fastcgi. Fastcgi can reduce the memory footprint (memory footprint) of Web servers and improve PHP performance. You can refer to this to configure Apache2 + PHP + FastCGI. In this configuration, cgi. force_redirect will prevent users from calling PHP by accessing the URL. To ensure security, enable this feature:
; Enable cgi.force_redirect for security reasons in a typical *Apache+PHP-CGI/FastCGI* setup cgi.force_redirect=On
#14: PHP user and user group ID
Mod_fastcgi is a cgi Module of Apache Web services and can be connected to external FASTCGI servers. Make sure that PHP runs with a non-root user. If the root or UID is less than 100 of the user permissions, it can access, and even operating system files. Through Apache's suEXEC or mod_suPHP, php cgi can be executed under non-privileged users. SuEXEC can be the user ID for Apache to call CGI programs, which is different from the user ID for running Apache. As follows:
# 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
You can use spawn-fcgi to generate a phpcgi user's remote or local FastCGI process (provided that this user is available ):
# spawn-fcgi -a 127.0.0.1 -p 9000 -u phpcgi -g phpcgi -f /usr/bin/php-cgi
Now you can configure Apache, Lighthttpd, or Nginx Web service calls to run FastCGI on 127.0.0.1: 9000.
#15: Restrict PHP access to the file system
Open_basedir limits the running directory of PHP, such as the directory accessible by functions such as fopen. If the accessed directory is not in open_basedir, PHP rejects the access. Do not use soft links as the workspace. For example, you can only access the/var/www/html directory instead of the/var/www,/tmp or/etc directory:
; 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/" ; ------------------------------------
#16: Session path
PHP Session users can save data for subsequent access. This makes the application more customizable and more attractive. All Session-related data is stored in session. save_path. The default settings for RHEL/CentOS/Fedora Linux are as follows:
session.save_path="/var/lib/php/session" ; Set the temporary directory used for storing files when doing file upload upload_tmp_dir="/var/lib/php/session"
Make sure the path is out of/var/www/html and cannot be accessed by other system users:
# ls -Z /var/lib/php/
Sample output:
drwxrwx---. root apache system_u:object_r:httpd_var_run_t:s0 session
Note: ls-Z displays SELinux security information, such as file mode, user, group, security information, and file name.
#17: ensure that PHP, software, and operating systems are updated to the latest
An important task of maintaining Linux, Apache, PHP, and MySQL servers is to update security patches. All PHP security updates should be reviewed and updated as soon as possible. Run the following command (If PHP is installed through the Package Manager ):
# yum update
Or
# apt-get update && apt-get upgrade
You can configure Red Hat/CentOS/Fedora Linux to send the yum package update reminder by Email or the apticron reminder In Debian/Ubuntu Linux. Or update the task through cron.
Note: View php.net to obtain the latest PHP version.
#18: Restrict access to files and directories
Run Apache with a non-root user such as Apache or www. The owner in the/var/www/html Directory should also be a non-root User:
# chown -R apache:apache /var/www/html/
Files under DocumentRoot should not be run or created. Set the File Permission in this directory to 0444 (read-only ):
# chmod -R 0444 /var/www/html/
Set all folder permissions in this directory to 0445
# find /var/www/html/ -type d -print0 | xargs -0 -I {} chmod 0445 {}
#19: Write protection for Apache, PHP, and MySQL configuration files
Use the chattr command to add write protection to these 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/
You can also add write protection to the/var/www/html directory.
# chattr +i /var/www/html/file1.php# chattr +i /var/www/html/
#20: Linux security expansion (such as SELinux)
Linux has various security solutions to prevent misconfiguration or vulnerabilities of service programs. Use SELinux or other Linux Security Solutions to restrict networks and programs. For example, SELinux provides different security policies for Linux kernel or Apache Web Services. Run the following command to list all Apache protection information:
# getsebool -a | grep httpd
Sample output:
allow_httpd_anon_write --> off allow_httpd_mod_auth_ntlm_winbind --> off allow_httpd_mod_auth_pam --> off allow_httpd_sys_script_anon_write --> off httpd_builtin_scripting --> on httpd_can_check_spam --> off httpd_can_network_connect --> off httpd_can_network_connect_cobbler --> off httpd_can_network_connect_db --> off httpd_can_network_memcache --> off httpd_can_network_relay --> off httpd_can_sendmail --> off httpd_dbus_avahi --> on httpd_enable_cgi --> on httpd_enable_ftp_server --> off httpd_enable_homedirs --> off httpd_execmem --> off httpd_read_user_content --> off httpd_setrlimit --> off httpd_ssi_exec --> off httpd_tmp_exec --> off httpd_tty_comm --> on httpd_unified --> on httpd_use_cifs --> off httpd_use_gpg --> off httpd_use_nfs --> off
To cancel Apache cgi, you can enter:
# setsebool -P httpd_enable_cgi off
For more information, see Red Hat SELinux guide.
#21: Install Mod_security
ModSecurity is an open-source Web application engine for intrusion detection and prevention. Installing mod_security can protect Apache and PHP applications from XSS and Other Attacks:
## A few Examples ## # Do not allow to open files in /etc/ SecFilter /etc/ # Stop SQL injection SecFilter "delete[[:space:]]+from" SecFilter "select.+from"
#22: if possible, run Apache/PHP under Chroot Jail
Running Apache/PHP under Chroot Jail can minimize possible losses and limit it to a small segment in the file system. You can use the common chroot to configure Apache: chroot kind of setup with Apache. However, we recommend that you use FreeBSD jails, XEN, KVM, or OpenVZ virtualization.
#23: Use a firewall to restrict outgoing connections
Attackers can use tools such as wget to download files from your Web server. Use iptables to block outgoing connections from Apache users. The ipt_owner module assigns different roles to the local data packet generator. It is only valid for the OUTPUT chain. The following command allows the vivek user to perform external access through port 80:
/sbin/iptables -A OUTPUT -o eth0 -m owner --uid-owner vivek -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
The following example blocks outgoing connections from all Apache users and only allows the smtp service and spam to identify API service passing through:
# .... /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 192.168.1.100 --dport 25 -j RETURN # Allow apache user to connec to api server for spam validation /sbin/iptables --append apache_user -p tcp --syn -d 66.135.58.62 --dport 80 -j RETURN /sbin/iptables --append apache_user -p tcp --syn -d 66.135.58.61 --dport 80 -j RETURN /sbin/iptables --append apache_user -p tcp --syn -d 72.233.69.89 --dport 80 -j RETURN /sbin/iptables --append apache_user -p tcp --syn -d 72.233.69.88 --dport 80 -j RETURN ######################### ## Add more rules here ## ######################### # No editing below # Drop everything for apache outgoing connection /sbin/iptables --append apache_user -j REJECT
#24: View and Review logs
View 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
View the PHP log file:
# tail -f /var/log/httpd/php_scripts_error.log # grep "...etc/passwd" /var/log/httpd/php_scripts_error.log
Viewing log files allows you to know what attacks the server is under and analyze whether the current security level is sufficient. Enable review service for System Review, which can review SELinux time, verification event, file modification, account modification, and so on. We recommend that you use Linux System Monitoring Tools to monitor Web servers.
#25: separating services from different servers or virtual machines
For a relatively large installation configuration, we recommend that you separate the running, database, static, and dynamic content from different servers.
/////////////// / ISP/Router / ////////////// \ | Firewall \ | +------------+ | LB01 | +------------+ +--------------------------+ | | static.lan.cyberciti.biz | +-----------------+--------------------------+ | phpcgi1.lan.cyberciti.biz| +--------------------------+ | phpcgi2.lan.cyberciti.biz| +--------------------------+ | mysql1.lan.cyberciti.biz | +--------------------------+ | mcache1.lan.cyberciti.biz| +--------------------------+
Run different network services on different servers or virtual machines to reduce the impact of intrusion on other services. For example, if an attacker intrude into Apache, other services (such as MySQL and email services) on the same server can be accessed ). However, in the above example, it does not:
- Static. lan. cybercity. biz-use lighttpd or nginx to store js, css, images, and other static Resources
- Phpcgi1.lan. cyberciti. biz and phpcgi2.lan. cyberciti. biz-Apache Web Service + PHP, used to generate dynamic content
- Mysql1.lan. cyberciti. biz-MySQL Database Service
- Mcache1.lan. cyberciti. biz-Memcached Service (MySQL high-speed cache system ). It uses libevent or epoll to adapt to any number of connections. It also uses non-blocking network I/O.
- LB01-An Nginx server used for reverse proxy of the Web and Apache front-end. All access connections are directly processed or distributed to the corresponding Web server through the nginx proxy service. LB01 provides simple load balancing.