How SQL injection Works
Constructing a database query is a very straightforward process. Typically, it will follow the following ideas. Just to illustrate the problem, we will assume that you have a
Wine database Table "Wines", which has a field of "variety" (i.e. wine type):
1. Provide a form-allows users to submit certain content to search for. Let's assume that the user chooses to search for a wine of type "Lagrein".
2. Retrieve the user's search term and save it-by assigning it to a variable that looks like this:
The code is as follows |
Copy Code |
$variety = $_post[' variety ']; |
Therefore, the value of the variable $variety is now:
Lagrein
3. Then, use the variable to construct a database query in the WHERE clause:
The code is as follows |
Copy Code |
$query = "SELECT * FROM Wines WHERE variety= ' $variety '"; |
Therefore, the value of the variable $query now looks like this:
The code is as follows |
Copy Code |
SELECT * FROM Wines WHERE variety= ' Lagrein ' |
4. Submit the query to the MySQL server.
5. mysql returns all records in the wines table-where the value of the field variety is "Lagrein".
So far, this should be a familiar and very relaxing process. Unfortunately, sometimes the processes we know and feel comfortable with are easy
Cause us to be complacent. Now, let's re-examine the query we just built.
1. The fixed portion of the query you create ends with a single quote, which you will use to describe the beginning of the variable value:
The code is as follows |
Copy Code |
$query = "SELECT * FROM wines WHERE variety = '"; |
2. Use the original invariant part and the value that contains the user-submitted variable:
The code is as follows |
Copy Code |
$query. = $variety; |
3. Then, you use another single quotation mark to connect to this result-to describe the end of the variable value:
The code is as follows |
Copy Code |
$ query. = "'"; |
Thus, the value of the $query is as follows:
The code is as follows |
Copy Code |
SELECT * FROM wines WHERE variety = ' Lagrein ' |
The success of this construct relies on the input of the user. In this example, you are using a single word (or maybe a group of words) to indicate a wine type.
As a result, the query is built without any problems, and the result will be what you would expect-a wine list with a wine type of "Lagrein". Is
In, let's imagine, since your users are not typing a simple type of wine that is "Lagrein", they enter the following content (note that the package
Enclose two punctuation marks):
The code is as follows |
Copy Code |
Lagrein ' or 1=1; |
Now, you continue to construct your query using the previously fixed sections (here, we only show the result values of the $query variable):
The code is as follows |
Copy Code |
SELECT * FROM wines WHERE variety = ' |
You then connect to it using the value of the variable containing the user's input (here, in bold):
The code is as follows |
Copy Code |
SELECT * FROM wines WHERE variety = ' lagrein ' or 1=1; |
Finally, add the following quote below:
The code is as follows |
Copy Code |
SELECT * FROM wines WHERE variety = ' lagrein ' or 1=1; ' |
Condensation of the above problems we write a function that can be prevented.
The code is as follows |
Copy Code |
/** +---------------------------------------------------------- * Anti-mount horse, anti-cross-site attack, anti-SQL injection function +------------- --------------------------------------------- * $date incoming arguments, if a variable or array; $ignore the magic Reference of the _magic_quotes variable +------- --------------------------------------------------- */ function in ($data, $ignore _magic_quotes=false) { if (is_string ($data)) { $data =trim (Htmlspecialchars ($data));//prevent horse from being hanged, cross station attack if (($ignore _magic_quotes==true) | | (!GET_MAGIC_QUOTES_GPC ())) { $data = addslashes ($data);//Prevent SQL injection  &NBSP} return $data; } else if (Is_array ($data))//If the array uses recursive filtering { foreach ($data as $key => $value) { $data [$key]=in ($value); return $data; &NBSP} else { return $data; } } |
When the above data is accepted we can prevent the horse from being hanged, cross station attack, prevent SQL injection waiting
Here's how to do security configuration on the server side
(1) Open PHP security mode
PHP's Safe mode is a very important embedded security mechanism that can control functions in PHP, such as System (),
At the same time, a lot of file operation functions are controlled by permissions, also do not allow some key file files, such as/etc/passwd,
But the default php.ini is not open safe mode, we turn it on:
Safe_mode = On
(2) User group security
When the Safe_mode is turned on, the Safe_mode_gid is turned off, so the PHP script can access the file and the same
Users of a group can also access files.
The recommended setting is:
Safe_mode_gid = Off
If you do not set it, we may not be able to operate on our server web directory files, such as we need
When you are working on a file.
(3) Safe Mode executable Program Home directory
If Safe mode is open, but you want to execute some programs, you can specify the home directory where you want to execute the program:
The code is as follows |
Copy Code |
Safe_mode_exec_dir = D:/usr/bin |
In general, there is no program to perform, so it is recommended not to execute the System program directory, you can point to a directory,
Then copy the program that needs to be executed, such as:
The code is as follows |
Copy Code |
Safe_mode_exec_dir = D:/tmp/cmd |
However, I recommend that you do not execute any programs, then you can point to our web directory:
The code is as follows |
Copy Code |
Safe_mode_exec_dir = d:/usr/www |
(4) Include files in Safe mode
If you want to include some public files in Safe mode, modify the options:
The code is as follows |
Copy Code |
Safe_mode_include_dir = d:/usr/www/include/ |
In fact, the general PHP script contains files are in the program itself has been written, this can be set according to the specific needs.
(5) Control the directory that the PHP script can access
Using the Open_basedir option to control PHP scripts can only access the specified directory, so that you can avoid PHP script access
Files that should not be accessed, to some extent limit the harm of phpshell, we can generally set to access only the site directory:
The code is as follows |
Copy Code |
Open_basedir = d:/usr/www |
(6) Close the dangerous function
If Safe mode is turned on, the function prohibition is not necessary, but we consider it for security. Like what
We don't feel like executing PHP functions that can execute commands, including system (), or can view PHP information
Phpinfo () and so on, then we can ban them:
The code is as follows |
Copy Code |
Disable_functions = System,passthru,exec,shell_exec,popen,phpinfo |
If you want to disable the operation of any files and directories, you can turn off many file operations
The code is as follows |
Copy Code |
Disable_functions = Chdir,chroot,dir,getcwd,opendir,readdir,scandir,fopen,unlink,delete,copy,mkdir, Rmdir,rename,file,file_get_contents,fputs,fwrite,chgrp,chmod,chown |
The above is just a list of not commonly used file processing functions, you can also perform the above command function and this function combined,
will be able to resist most of the Phpshell.
(7) Turn off the disclosure of PHP version information in HTTP headers
In order to prevent hackers from obtaining information about the PHP version of the server, you can turn off the information ramp in the HTTP header:
The code is as follows |
Copy Code |
expose_php = Off |
For example, when the hacker in Telnet www.12345.com 80, then will not be able to see the PHP information.
(8) Turning off registration of global variables
Variables submitted in PHP, including those submitted using post or get, are automatically registered as global variables and can be accessed directly.
This is very unsafe for the server, so we cannot have it registered as a global variable and turn off the registration global variable option:
The code is as follows |
Copy Code |
Register_globals = Off |
Of course, if you set this up, then you need to get the corresponding variable in a reasonable way, such as getting the variable var of get commit,
Then you need to use $_get[' var ' to get it, the PHP programmer should pay attention.
(9) Open MAGIC_QUOTES_GPC to prevent SQL injection
SQL injection is a very dangerous problem, small web site backstage was invaded, heavy the entire server fell,
So be sure to be careful. There is a setting in php.ini:
The code is as follows |
Copy Code |
MAGIC_QUOTES_GPC = Off |
This default is turned off, and if it is turned on, it will automatically convert the user to the SQL query.
For example, the ' switch ' and so on, which has a significant effect on preventing SQL injection. So we recommend setting it to:
The code is as follows |
Copy Code |
MAGIC_QUOTES_GPC = On |
(10) Error information control
General PHP is not connected to the database or other circumstances will be prompted error, the general error message will contain PHP script when
Before the path information or query SQL statements, such as information, such information provided to hackers, is not secure, so the general server recommended to prohibit error prompts:
The code is as follows |
Copy Code |
Display_errors = Off |
If you are trying to display an error message, be sure to set the level at which the error is displayed, such as displaying only the information above the warning:
The code is as follows |
Copy Code |
error_reporting = e_warning & E_error |
Of course, I recommend closing the error prompt.
(11) Error log
It is recommended that the error message can be logged after the display_errors is turned off to make it easier to find out why the server is running:
The code is as follows |
Copy Code |
Log_errors = On |
Also set the directory where the error log is stored, and suggest that the log of the root Apache be present together:
The code is as follows |
Copy Code |
Error_log = D:/usr/local/apache2/logs/php_error.log |
Note: You must allow the Apache users and groups to have write permissions to the file.
MySQL's Down right run
Create a new user like Mysqlstart
The code is as follows |
Copy Code |
NET user Mysqlstart Fuckmicrosoft/add net localgroup users Mysqlstart/del |
Does not belong to any group
If MySQL is installed in D:mysql, then give Mysqlstart Full control of the permissions
Then in the system service settings, MySQL service properties, in the login attribute, select this user mysqlstart then enter the password, OK.
Restart the MySQL service, and MySQL runs under low privileges.
If you're building Apache under the WinDOS platform, we need to be aware that Apache runs by default is System privilege,
It was scary, and it made people feel uncomfortable. Then let's give Apache a drop in privileges.
The code is as follows |
Copy Code |
NET user Apache Fuckmicrosoft/add net localgroup users Apache/del |
OK. We have established a user apche that does not belong to any group.
We open the Computer Manager, select the service, point Apache Service Properties, we select Log on, choose this account, we fill in the above established
's account and password,
Restart the Apache service, Ok,apache running under low privileges.
In fact, we can also set the permissions of each folder, so that the Apache users can only do what we want it to do, for each directory to create
A user who can read and write alone
This article from the program to the database and the final configuration of the Web server has been described, we refer to this article should be safe a lot of oh, the general injection
There is no way to achieve it.