The prevention method and injection analysis of SQL injection attack in PHP

Source: Internet
Author: User
Tags ini mysql functions mysql injection mysql tutorial numeric value php script sql injection sql injection attack

1. The MAGIC_QUOTES_GPC option in the PHP tutorial configuration file php.ini is not turned on and is set to off 2. The developer did not check and escape the data type

But in fact, the 2nd is the most important. I think that it is the most basic quality of a web programmer to check the data type entered by the user and submit the correct data type to the MySQL tutorial. But in reality, many small white web developers often forget this, leading to a backdoor opening.

Why is the 2nd most important? Because without a 2nd guarantee, the MAGIC_QUOTES_GPC option, whether on or off, can trigger a SQL injection attack. Here's a look at the technology implementation:

A. MAGIC_QUOTES_GPC = injection attack at off

MAGIC_QUOTES_GPC = Off is a very unsafe option in PHP. The new version of PHP has changed the default value to ON. However, there are still a considerable number of servers with the option off. After all, the antique server is also used by others.

When MAGIC_QUOTES_GPC = ON, it automatically adds all the "(single quotes)," (double), (backslash), white-space characters in the submitted variable to the front. The following is an official description of PHP:

View Sourceprint?

MAGIC_QUOTES_GPC Boolean

Sets the Magic_quotes state for GPC (Get/post/cookie) operations. When magic_quotes are in, all ' (Single-quote), "(double quote), (backslash) and Nul's are escaped with a backslash autom Atically

If the


is not escaped, that is, off, the attacker can take advantage of it. Take the following test script as an example:

 1<?
 2if (Isset ($_post["F_login"))
 3{
 4 //Connecting to the database tutorial ...
 5 //... Code slightly ...
 6
 7 //Check if the user exists
 8  $t _struname = $_post["F_uname"];
 9  $t _STRPW D = $_post["F_pwd"];
10  $t _strsql = "SELECT * from tbl_users where username= ' $t _struname ' and password = ' $t _strpwd ' limit 0,1";
One
12  if ($t _hres = mysql_query ($t _strsql))
13  {
14   //After successful query processing.
15 }
16}
17?>

19 20< Body>
21<form method=post action= ""
22  Username: <input type= "text" name= "F_uname" size=30 ><br>
23  Password: <input type=text name= "F_pwd" SIZE=30><BR>

25  < Input type= "Submit" Name= "F_login" value= "Login" "
26</form>
27</body>

In this script, when the user enters a normal username and password, assuming the value is Zhang3, abc123, the submitted SQL statement is as follows:

1 SELECT * FROM tbl_users
2 where username= ' zhang3 ' and password = ' abc123 ' limit 0,1


If an attacker enters the Zhang3 ' or 1=1 # in the Username field and enters abc123 in password, the submitted SQL statement becomes the following:

1 SELECT * FROM tbl_users
2 where username= ' Zhang3 ' or 1=1 # ' and password = ' abc123 ' limit 0,1


Because # is the annotation character in MySQL, #之后的语句不被执行, the implementation of this line statement becomes:

1 SELECT * FROM tbl_users
2 where username= ' Zhang3 ' or 1=1


This will allow the attacker to bypass authentication. If the attacker knew the structure of the database, it would be more dangerous to build a union select:

Suppose to enter in Username: Zhang3 ' or 1 =1 Union select Cola, colb,cold from Tbl_b #

In Password input: abc123,

Then the submitted SQL statement becomes:

1 SELECT * FROM tbl_users
2 where username= ' Zhang3 '
3 or 1 =1 Union select Cola, colb,cold from Tbl_b # ' and password = ' abc123 ' limit 0,1


This is quite dangerous. If the AGIC_QUOTES_GPC option is on and the quotation marks are escaped, then the attack statements built by the attacker above will become this way and cannot achieve their purpose:

1 SELECT * FROM tbl_users
2 where username= ' Zhang3 ' or 1=1 # '
3 and Password = ' abc123 '
4 Limit 0,1
5
6 SELECT * FROM Tbl_users
7 where username= ' Zhang3 ' or 1 =1 Union select Cola, colb,cold from Tbl_b # '
8 and Password = ' abc123 ' limit 0,1


Two. MAGIC_QUOTES_GPC = injection attack on

When MAGIC_QUOTES_GPC = ON, an attacker cannot inject SQL into a character-type field. That doesn't mean it's safe. In this case, you can use the numeric fields for SQL injection.

In the latest version of MySQL 5.x, the data type has been strictly entered, and automatic type conversion has been turned off by default. A field of numeric type, which cannot be a character type that is quoted as a quotation mark. In other words, suppose the UID is numeric, and in previous versions of MySQL, such statements were legal:

1 INSERT INTO Tbl_user set uid= "1";
2 Select * from Tbl_user where uid= "1";


In the latest MySQL 5.x, the above statement is not legal and must be written like this:

1 INSERT into Tbl_user set uid=1;
2 Select * from Tbl_user where uid=1;


So I think it's right. Because as a developer, submitting the correct conforming data type to the database is the most basic requirement.

So how do attackers attack when MAGIC_QUOTES_GPC = on? The simple thing is to inject SQL into the field of a numeric type. Take the following PHP script as an example:

1.?
2 if (Isset ($_post["F_login"))
3 {
4//Connection Database ...
5//... Code slightly ...
6
7//Check whether the user exists
8 $t _struid = $_post["F_uid"];
9 $t _strpwd = $_post["F_pwd"];
$t _strsql = "SELECT * from tbl_users where uid= $t _struid and password = ' $t _strpwd ' limit 0,1 ';
One if ($t _hres = mysql_query ($t _strsql))
12 {
13//After the successful query processing. Slightly...
14}
15
16}
?>
<body>
<form method=post action= "" >
User id: <input type= "text" name= "F_uid" size=30><br>
22
Password: <input type=text name= "F_pwd" size=30><br>
<input type= "Submit" Name= "F_login" value= "Login" >
</form>
Num </body>


The above script requires the user to enter UserID and password login. A normal statement, the user enters 1001 and abc123, submits the SQL statement as follows:

SELECT * from tbl_users where userid=1001 and password = ' abc123 ' limit 0,1

If the attacker is at UserID, enter: 1001 or 1 = 1 #, the injected SQL statement is as follows:

SELECT * from tbl_users where userid=1001 or 1 =1 # and password = ' abc123 ' limit 0,1

The attackers achieved their purpose.

Three. How to prevent PHP SQL injection attacks

How do I prevent PHP SQL injection attacks? I think the most important thing is to check and escape the data type. Some of the rules summarized are as follows:

The display_errors option in php.ini should be set to Display_errors = off. This way, the PHP script does not output errors on the Web page, so that the attacker can parse out the information.

When calling MySQL functions such as mysql_query, you should precede the @, that is @mysql_query (...), so that the MySQL error will not be output. In the same vein, the attacker is not allowed to analyze useful information. In addition, some programmers in the development, when mysql_query error, custom output errors and SQL statements, such as: 1 $t _strsql = "Select a from B ...";
2 if (mysql_query ($t _strsql))
3 {
4//correct handling
5}
6 Else
7 {
8 echo "Error! SQL statement: $t _strsql RN error message ". mysql_query ();
9 exit;
10}


This practice is quite dangerous and stupid. If you do this, it's a good idea to set a global variable or define a macro in your site's configuration file to set the debug flag:

1//Global configuration file:
2 define ("Debug_mode", 0); 1:debug mode; 0:release mode
3
4//Calling script:
5 $t _strsql = "Select a from B ...";
6 if (mysql_query ($t _strsql))
7 {
8//correct handling
3 ·
Ten Else
11 {
if (Debug_mode)
echo "Error! SQL statement: $t _strsql RN error message ". mysql_query ();
Exit;
15}


An escape and type check for the submitted SQL statement.

Four. I write a security parameter get function

To prevent user error data and PHP + MySQL injection, I wrote a function papi_getsafeparam () to get the safe parameter values:

1 define ("Xh_param_int", 0);
2 define ("Xh_param_txt", 1);
3 function Papi_getsafeparam ($pi _strname, $pi _def = "", $pi _itype = xh_param_txt)
4 {
5 if (isset ($_get[$pi _strname]))
6 $t _val = Trim ($_get[$pi _strname]);
7 Else if (Isset ($_post[$pi _strname]))
8 $t _val = Trim ($_post[$pi _strname]);
9 Else
Ten return $PI _def;
11
A//INT
if (Xh_param_int = = $pi _itype)
14 {
if (Is_numeric ($t _val))
$t _val;
Or else
return $PI _def;
19}
20
/String
$t _val = Str_replace ("&", "&amp;", $t _val);
$t _val = Str_replace ("<", "&lt;", $t _val);
$t _val = Str_replace (">", "&gt;", $t _val);
if (GET_MAGIC_QUOTES_GPC ())
26 {
$t _val = Str_replace (""", "&quot;", $t _val);
$t _val = Str_replace ("" "," & #039; ", $t _val);
29}
Or else
31 {
$t _val = Str_replace ("" "," &quot; ", $t _val);
$t _val = Str_replace ("'", "& #039;", $t _val);
34}
$t _val;
+}


In this function, there are three parameters:

$PI _strname: Variable name
$PI _def: Default value
$PI _itype: Data type. The value is Xh_param_int, Xh_param_txt, representing the numeric and textual types respectively.


If the request is a numeric type, then call Is_numeric () to determine whether it is a numeric value. If it is not, the default value specified by the program is returned.

For simplicity, for a text string, I escape all the dangerous characters (including the HTML code) that the user enters. Because the PHP function addslashes () there is a vulnerability, I use Str_replace () directly replace. The GET_MAGIC_QUOTES_GPC () function is a PHP function that is used to determine whether the MAGIC_QUOTES_GPC option is open.

For the example in the second section, the code can call this:

1.?
2 if (Isset ($_post["F_login"))
3 {
4//Connection Database ...
5//... Code slightly ...
6
7//Check whether the user exists
8 $t _struid = Papi_getsafeparam ("F_uid", 0, Xh_param_int);
9 $t _strpwd = Papi_getsafeparam ("F_pwd", "", xh_param_txt);
$t _strsql = "SELECT * from tbl_users where uid= $t _struid and password = ' $t _strpwd ' limit 0,1 ';
One if ($t _hres = mysql_query ($t _strsql))
12 {
13//After the successful query processing. Slightly...
14}
15}
?>

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.