Home  >  Article  >  Backend Development  >  Technical implementation and prevention methods of PHP+SQL injection attacks_PHP tutorial

Technical implementation and prevention methods of PHP+SQL injection attacks_PHP tutorial

WBOY
WBOYOriginal
2016-07-21 15:32:40828browse

Summarize the experience. In my opinion, the main cause of SQL injection attacks is the following two reasons:
1. The magic_quotes_gpc option in the php configuration file php.ini is not turned on and is set to off
2. The developer does not Check and escape data types
But in fact, the second point is the most important. I think that checking the data type 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 novice web developers often forget this, leaving the backdoor wide open.
Why is the second point the most important? Because without the second guarantee, the magic_quotes_gpc option, whether it is on or off, may cause SQL injection attacks. Let’s take a look at the technical implementation:
1. Injection attack when magic_quotes_gpc = Off
Magic_quotes_gpc = Off is a very unsafe option in PHP. The new version of php has changed the default value to On. But there are still quite a few servers with the option off. After all, no matter how antique the server is, there are still people using it.
When magic_quotes_gpc = On, it will automatically add all '(single quotes), "(double signs), (backslashes), and whitespace characters in the submitted variables in front. The following is Official description of php:

Copy code The code is as follows:

magic_quotes_gpc boolean

Sets the magic_quotes state for GPC (Get/Post/Cookie) operations. When magic_quotes are on, all ' (single-quote), " (double quote), (backslash) and NUL's are escaped with a backslash automatically

If there is no escape, that is, in the off case, it will give attackers an opportunity to take advantage. Take the following test script as an example:
Copy code The code is as follows:

if ( isset($ _POST["f_login"] ) )
{
// Connect to the database...
// ...The code is omitted...

// Check whether 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 successful query. Omitted...
}
}
?>

sample test


Username:

Password:






In this script, when the user enters a normal username and password, assuming the values ​​are zhang3 and abc123 respectively, the submitted SQL statement is as follows:
Copy Code The code is as follows:

SELECT * FROM tbl_users
WHERE username='zhang3' AND password = 'abc123' LIMIT 0,1

If the attacker enters: zhang3' OR 1=1 # in the username field and abc123 in the password field, the submitted SQL statement becomes as follows:
Copy code The code is as follows:

SELECT * FROM tbl_users
WHERE username='zhang3' OR 1=1 #' AND password = 'abc123' LIMIT 0,1

Since # is a comment character in mysql, the statement after # will not be executed. To implement this line of statement, it becomes:
Copy code The code is as follows :

SELECT * FROM tbl_users
WHERE username='zhang3' OR 1=1

 This way the attacker can bypass authentication. If the attacker knows the database structure, it is even more dangerous if he constructs a UNION SELECT:

Suppose you enter in username: zhang3 ' OR 1 =1 UNION select cola, colb,cold FROM tbl_b #

Input password: abc123,

Then the submitted SQL statement becomes:
Copy code The 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 quotes are escaped, the attack statement constructed by the attacker above will become like this, thus failing to achieve its purpose:
Copy code The 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

2. Injection attack when magic_quotes_gpc = On
When magic_quotes_gpc = On, the attacker cannot perform SQL injection on character fields. That doesn't mean it's safe. At this time, SQL injection can be performed through numeric fields.

In the latest version of MYSQL 5.x, the input of data types has been stricted, and automatic type conversion has been turned off by default. Numeric fields cannot be character types marked with quotation marks. In other words, assuming uid is numeric, in previous mysql versions, such a statement is legal:
Copy code The code is as follows:

INSERT INTO tbl_user SET uid="1";
SELECT * FROM tbl_user WHERE uid="1";

In the latest MYSQL 5.x, above The statement is not legal and must be written like this:
Copy code The code is as follows:

INSERT INTO tbl_user SET uid=1;
SELECT * FROM tbl_user WHERE uid=1;

I think this is correct. Because as a developer, submitting correct data types that comply with the rules to the database is the most basic requirement.

So how do attackers attack when magic_quotes_gpc = On? It's very simple, just perform SQL injection on numeric fields. Take the following php script as an example:
Copy code The code is as follows:

if ( isset( $_POST["f_login"] ) )
{
// Connect to the database...
// ...The code is abbreviated...

// Check whether 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 successful query. Omitted...
}

}
?>
sample test


User ID:


Password:






The above script requires the user to enter userid and password to log in. A normal statement, the user inputs 1001 and abc123, and the submitted sql statement is as follows:

SELECT * FROM tbl_users WHERE userid=1001 AND password = 'abc123' LIMIT 0,1
 If the attacker is at userid , input: 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
Attack The person achieved his goal.

3. How to prevent PHP SQL injection attacks
How to prevent PHP SQL injection attacks? I think the most important point is to check and escape data types. The summarized rules are as follows:

The display_errors option in php.ini should be set to display_errors = off. In this way, after an error occurs in the php script, the error will not be output on the web page to prevent attackers from analyzing useful information.
When calling mysql functions such as mysql_query, @ should be added in front, that is, @mysql_query(...), so that mysql errors will not be output. The same is true to prevent attackers from analyzing useful information. In addition, some programmers are used to outputting errors and sql statements when mysql_query errors when developing, for example:
Copy code The code is as follows:

$t_strSQL = "SELECT a from b....";
if ( mysql_query($t_strSQL) )
{
// Correct processing
}
else
{
echo "Error! SQL statement: $t_strSQL rn error message".mysql_query();
exit;
}

This approach is quite dangerous and stupid. If you must do this, it is best to set a global variable or define a macro in the website configuration file and set the debug flag:

In the global configuration file:
Copy code The code is as follows:

define("DEBUG_MODE",0); // 1: DEBUG MODE; 0: RELEASE MODE

// In the calling script:
$t_strSQL = "SELECT a from b....";
if ( mysql_query($t_strSQL) )
{
// Correct processing
}
else
{
if (DEBUG_MODE)
echo "Error! SQL statement: $t_strSQL rnerror message".mysql_query();
exit;
}

Escape and type check the submitted sql statement.
IV. A safe parameter acquisition function I wrote
In order to prevent users from erroneous data and php + mysql injection, I wrote a function PAPI_GetSafeParam() to obtain safe parameter values:
Copy code The 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 ( 🎜>}

// 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 values ​​are XH_PARAM_INT and XH_PARAM_TXT, which represent numeric type and text type respectively.
If the request is numeric, then call is_numeric() to determine whether it is a numeric value. If not, the program-specified default value is returned.

For the sake of simplicity, for text strings, I escape all dangerous characters (including HTML codes) entered by the user. Since the php function addslashes() has a vulnerability, I directly replaced it with str_replace(). The get_magic_quotes_gpc() function is a PHP function, used to determine whether the magic_quotes_gpc option is turned on.


In the example in the second section, the code can be called like this:



Copy the code

The code is as follows:
if ( isset($_POST["f_login"] ) ) { // Connect to the database...
// ...code abbreviated...

//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) )
{
// Successful query The subsequent processing. Slightly...
}
}
?>


In this case, it is already quite safe. The code of PAPI_GetSafeParam is a bit long, but it is worth sacrificing this efficiency to ensure security. I hope everyone can criticize and correct me more. :)



http://www.bkjia.com/PHPjc/322736.html

www.bkjia.com

true

TechArticle Summarize the experience. In my opinion, the main cause of SQL injection attacks is the following two reasons: 1. The magic_quotes_gpc option in the php configuration file php.ini is not turned on and is...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn