The technical implementation of PHP+SQL injection attack and the prevention method _php tutorial

Source: Internet
Author: User
Tags mysql injection sql injection attack
Summarize your experience. In my opinion, the main reason for the SQL injection attack is due to the following two reasons:
1. The MAGIC_QUOTES_GPC option in PHP config file php.ini is not turned on and is set to off
2. The developer does not check and escape the data type
But in fact, the 2nd is the most important. I think that checking the type of data entered by the user and submitting the correct data type to MYSQL should be the most basic quality of a web programmer. But in reality, many small white Web developers often forget this, causing the backdoor to open.
Why is 2nd the most important? Because without the 2nd guarantee, the MAGIC_QUOTES_GPC option, whether on or off, could trigger a SQL injection attack. Here's a look at the technology implementation:
one. MAGIC_QUOTES_GPC = Off Injection Attack
MAGIC_QUOTES_GPC = Off is a very insecure option in PHP. The new version of PHP has changed the default value to ON. However, there are still quite a few options for the server to OFF. After all, the antique servers are also used by people.
When MAGIC_QUOTES_GPC = ON, it will put all the ' (single quotation marks), "(double number), \ (backslash), and white space characters of the submitted variable in the front automatically. The following is an official description of PHP:

Copy CodeThe code is as follows:
MAGIC_QUOTES_GPC Boolean

Sets the Magic_quotes state for GPC (Get/post/cookie) operations. When Magic_quotes is on, all ' (Single-quote), "(double quote), \ (backslash) and NUL ' s is escaped with a backslash aut Omatically

If it is not escaped, that is off, it gives the attacker an advantage. Take the following test script as an example:
Copy CodeThe code is as follows:
if (Isset ($_post["F_login"))
{
Connect to Database ...
// ... Code slightly ...

Check if the user exists
$t _struname = $_post["F_uname"];
$t _strpwd = $_post["F_pwd"];
$t _strsql = "SELECT * from tbl_users WHERE username= ' $t _struname ' and password = ' $t _strpwd ' LIMIT 0,1 ';

if ($t _hres = mysql_query ($t _strsql))
{
Processing after a successful query. Slightly...
}
}
?>

<title>Sample test</title>




In this script, when the user enters a normal user name and password, assuming that the values are Zhang3, abc123, the SQL statement that is submitted is as follows:
Copy CodeThe code is as follows:
SELECT * from Tbl_users
WHERE username= ' zhang3 ' and password = ' abc123 ' LIMIT 0,1

If an attacker enters in the username field: Zhang3 ' OR 1=1 #, in Password input abc123, the submitted SQL statement becomes as follows:
Copy CodeThe code is as follows:
SELECT * from Tbl_users
WHERE username= ' Zhang3 ' OR 1=1 # ' and password = ' abc123 ' LIMIT 0,1

Since # is an annotation in MySQL, #之后的语句不被执行, the implementation of this line of statements becomes:
Copy CodeThe code is as follows:
SELECT * from Tbl_users
WHERE username= ' zhang3 ' OR 1=1

This allows the attacker to bypass authentication. If an attacker knew the database structure, it would be more dangerous to build a UNION SELECT:

Suppose you enter in Username: Zhang3 ' OR 1 =1 UNION Select Cola, colb,cold from Tbl_b #

In Password input: abc123,

The SQL statement that is committed becomes:
Copy CodeThe code is as follows:
SELECT * from Tbl_users
WHERE username= ' Zhang3 '

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, the attack statement built by the attacker above will become so that it does not achieve its purpose:
Copy CodeThe code is as follows:
SELECT * from Tbl_users
WHERE username= ' zhang3\ ' OR 1=1 # '
and password = ' abc123 '
LIMIT 0,1

SELECT * from Tbl_users
WHERE username= ' zhang3 \ ' OR 1 =1 UNION Select Cola, colb,cold from Tbl_b # '
and password = ' abc123 ' LIMIT 0,1

Two. MAGIC_QUOTES_GPC = injection attack at 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, SQL injection can be done with numeric fields.

In the latest version of MYSQL 5.x, data type input has been strictly, and automatic type conversion has been turned off by default. Numeric field, cannot be a character type of quotation marks. That is, assuming the UID is numeric, in the previous MySQL version, such statements are legal:
Copy CodeThe code is as follows:
INSERT into Tbl_user SET uid= "1";
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:
Copy CodeThe code is as follows:
INSERT into Tbl_user SET uid=1;
SELECT * from Tbl_user WHERE uid=1;

So I think it's right. Because as a developer, it is the most basic requirement to submit the correct rules-compliant data types to the database.

So how do attackers attack when MAGIC_QUOTES_GPC = on? It's easy to do SQL injection on numeric fields. Take the following PHP script as an example:
Copy CodeThe code is as follows:
if (Isset ($_post["F_login"))
{
Connect to Database ...
// ... Code slightly ...

Check if the user exists
$t _struid = $_post["F_uid"];
$t _strpwd = $_post["F_pwd"];
$t _strsql = "SELECT * from Tbl_users WHERE uid= $t _struid and password = ' $t _strpwd ' LIMIT 0,1 ';
if ($t _hres = mysql_query ($t _strsql))
{
Processing after a successful query. Slightly...
}

}
?>
<title>Sample test</title>





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

SELECT * from tbl_users WHERE userid=1001 and password = ' abc123 ' LIMIT 0,1
If the attacker is at the UserID, enter: 1001 OR 1 = 1 #, the SQL statement injected 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 are summarized as follows:

The display_errors option in php.ini should be set to Display_errors = off. In this way, the PHP script does not output errors in the Web page after the error, so that the attacker could parse out the information.
When you call a MySQL function such as mysql_query, you should precede it with @, which is @mysql_query (...) so that the MySQL error is not output. In the same vein, the attacker is not allowed to parse out useful information. In addition, some programmers in the development, when mysql_query error, used to output errors and SQL statements, such as:
Copy CodeThe code is as follows:
$t _strsql = "Select a from B ...";
if (mysql_query ($t _strsql))
{
The right treatment
}
Else
{
echo "Error! SQL statement: $t _strsql \ r \ n error message ". mysql_query ();
Exit
}

This practice is quite dangerous and foolish. If you must do this, it is best to set a global variable or define a macro in the configuration file of the Web site, and set the debug flag:

In the global configuration file:
Copy CodeThe code is as follows:
Define ("Debug_mode", 0); 1:debug MODE; 0:release MODE

In the call script:
$t _strsql = "Select a from B ...";
if (mysql_query ($t _strsql))
{
The right treatment
}
Else
{
if (Debug_mode)
echo "Error! SQL statement: $t _strsql \ r \ n error message ". mysql_query ();
Exit
}

Escape and type check for the SQL statement that was committed.
Four. I wrote a security parameter to get the function
To prevent user error data and PHP + MySQL injection, I wrote a function papi_getsafeparam () to get the safe parameter values:
Copy CodeThe code is as follows:
Define ("Xh_param_int", 0);
Define ("Xh_param_txt", 1);
function Papi_getsafeparam ($pi _strname, $pi _def = "", $pi _itype = xh_param_txt)
{
if (Isset ($_get[$pi _strname]))
$t _val = Trim ($_get[$pi _strname]);
else if (isset ($_post[$pi _strname]))
$t _val = Trim ($_post[$pi _strname]);
Else
return $PI _def;

Int
if (Xh_param_int = = $pi _itype)
{
if (Is_numeric ($t _val))
return $t _val;
Else
return $PI _def;
}

String
$t _val = Str_replace ("&", "&", $t _val);
$t _val = Str_replace ("<", "<", $t _val);
$t _val = Str_replace (">", ">", $t _val);
if (GET_MAGIC_QUOTES_GPC ())
{
$t _val = Str_replace ("\\\" "," "", $t _val);
$t _val = str_replace ("\ \" "," ' ", $t _val);
}
Else
{
$t _val = str_replace ("\" "," "", $t _val);
$t _val = Str_replace ("'", "'", $t _val);
}
return $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, respectively, the numeric type and the text type.
If the request is numeric, call Is_numeric () to determine whether it is a numeric value. If not, the default value specified by the program is returned.

For simplicity, for a text string, I escaped all dangerous characters (including HTML code) entered by the user. Because of a vulnerability in PHP function addslashes (), I replaced it directly with Str_replace (). The GET_MAGIC_QUOTES_GPC () function is a PHP function used to determine whether the MAGIC_QUOTES_GPC option is open.


Just in the second section of the example, the code can be called:
Copy CodeThe code is as follows:
if (Isset ($_post["F_login"))
{
Connect to Database ...
// ... Code slightly ...

Check if the user exists
$t _struid = Papi_getsafeparam ("F_uid", 0, Xh_param_int);
$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 ';
if ($t _hres = mysql_query ($t _strsql))
{
Processing after a successful query. Slightly...
}
}
?>

In that case, it's pretty safe. Papi_getsafeparam's code is a bit long, but sacrificing this efficiency is worth it to keep it safe. I hope you will criticize me more. :)

http://www.bkjia.com/PHPjc/322736.html www.bkjia.com true http://www.bkjia.com/PHPjc/322736.html techarticle summarize your experience. In my opinion, the main reason for the SQL injection attack is because of the following two reasons: 1. The MAGIC_QUOTES_GPC option in PHP config file php.ini is not open and is ...

  • 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.