Original: PHP Security programming-sql injection attack
PHP Security Programming--sql injection attack definition
- The SQL injection attack refers to the introduction of a special input as a parameter to the Web application, which is mostly a combination of SQL syntax, the execution of SQL statements to perform the actions of the attacker, the main reason is that the program does not carefully filter the user input data, resulting in illegal data intrusion system.
According to the relevant technology principle, SQL injection can be divided into platform layer injection and Code layer injection. The former is caused by an insecure database configuration or a vulnerability to a database platform, which is mainly due to the fact that the programmer has not carefully filtered the input, thus executing the illegal data query. Based on this, the cause of SQL injection usually manifests in the following aspects:
- inappropriate types of treatment;
- insecure database configuration;
- Unreasonable query set processing;
- improper handling of errors;
- The escape character processing is not appropriate;
- Multiple commits are improperly handled.
In some forms, user-entered content is used directly to construct dynamic SQL commands, or as input parameters to stored procedures, which are particularly susceptible to SQL injection attacks. While many web-site programs are written, there is no judgment on the legality of user input or improper handling of the variables in the program, which makes the application security hidden trouble. In this way, the user can submit a database query code, according to the results returned by the program to obtain some sensitive information or control the entire server, so SQL injection occurs
Common technology
- Force error generation
Identifying information such as database type, version, and so on is the motivation for this type of attack. Its purpose is to gather information about the type and structure of the database to prepare for other types of attacks, which are a preliminary step in the attack. Take advantage of the default error message returned by the application server to obtain the vulnerability information.
- Use of non-mainstream channel technology
In addition to the HTTP response, the data can be obtained through the channel, however, the channel is mostly dependent on the functionality supported by the database, so this technology is not fully applicable to all database platforms. SQL injection of non-mainstream channels are mainly e-mail, DNS and database connection, the basic idea is: first to package the SQL query, and then the use of non-mainstream channel will be feedback to the attacker.
- Use a special character
There are many different SQL databases with special characters and variables, and some useful information can be obtained through some configuration insecure or non-granular application systems to provide direction for further attacks.
- Using conditional statements
This method can be divided into content-based, time-based, error-based three forms. Generally after regular access to add conditional statements, according to information feedback to determine the target of the attack
- Take advantage of stored procedures
Through some standard stored procedures, the database vendor extends the function of the database, and the system can interact with it. Some stored procedures can be customized for the user. The command to execute a stored procedure can be constructed after other types of attacks collect information such as the type and structure of the database. This type of attack often achieves the purpose of remote command execution, privileged expansion, and denial of service.
- Avoid input filtering technology
Although some filtering techniques can be used for SQL injection prevention for the usual coding, there are many ways to avoid filtering in this case, including the use of SQL annotations and dynamic queries, using truncation, URL encoding, and null byte usage. Use of case variants and nested post-split expressions, and so on. With this approach, input-based queries can avoid input filtering, allowing attackers to obtain the desired query results.
- Inference Technology
The ability to define database schemas, extract data, and identify the parameters that can be injected. This kind of attack through the website to the user input feedback information, to the injection parameter, the database pattern inference, this kind of attack constructs the query execution to obtain the answer only true, the false two kinds. The injection method based on inference is divided into two kinds: time measurement injection and blind injection. The former is to add a statement such as "WAITFOR 100" in the injection statement, according to the time of the query results to determine the success of injection and the range of data values, the latter is mainly "and l=l", "and l=2" two classical injection methods. These are questions that are indirectly correlated and can be responded to, and then infer the desired information through the response information and then attack
Precautionary approach
Force character formatting (type)
- For shaping variables, use the Intval function to convert the data into integers
- Floating-point parameters: Convert single-and double-precision floating-point parameters using Floatval or Doubleval functions, respectively
- Character parameter: Use Addslashes function to convert single quotation mark "'" to "\" ", double quotation mark" "" "", "" "" "", "" "," "", "" "" "", "" "," null "character plus backslash" \ "If it is character type, first judge whether MAGIC_QUOTES_GPC is on, Use Addslashes to escape special characters when not on
- The production environment shuts down the database error prompt to prevent attackers from getting information about the database.
- Include variable quotes in SQL statements
SELECT * FROM article WHERE articleid=‘$id‘
Without putting the variable in single quotes, everything we commit, as long as it contains a space, the variable after the space is executed as an SQL statement, giving the attacker the possibility of constructing a special SQL statement. So, let's get into the habit of quoting variables in SQL statements.
Use PDO to use prepared statements (preprocessing statements) and parameterized queries. These SQL statements are sent to the database server, and its parameters are all parsed separately. In this way, it is not possible for an attacker to inject malicious SQL
When using PDO to access the MySQL database, real real prepared statements is not used by default. To solve this problem, you must disable the emulation effect of prepared statements. Here's an example of creating a link using PDO:
<?php $dbh = new PDO('mysql:dbname=mydb;host=127.0.0.1;charset=utf8', 'root', 'pass'); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); ?>
This ensures that SQL statements and corresponding values are not parsed by PHP until they are passed to the MySQL server (all possible malicious SQL injection attacks are prohibited)
Complete Sample code:
<?php $dbh = new PDO("mysql:host=localhost; dbname=mydb", "root", "pass"); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //禁用prepared statements的仿真效果 $dbh->exec("set names 'utf8'"); $sql="select * from table where username = ? and password = ?"; $query = $dbh->prepare($sql); $exeres = $query->execute(array($username, $pass)); if ($exeres) { while ($row = $query->fetch(PDO::FETCH_ASSOC)) { print_r($row); } } $dbh = null; ?>
When prepare () is called, the query statement has been sent to the database server with only placeholders at this time? Send in the past, no user submitted data, when called to execute (), the user submitted values will be sent to the database, they are separate transmission, the two independent, SQL attackers do not have a chance.
In the following cases, PDO prepared statements will not play a defensive role
- Pdo::attr_emulate_prepares enables or disables impersonation of preprocessing statements. Some drivers do not support or support local preprocessing in a limited way. Use this setting to force PDO to always impersonate a preprocessing statement (if true), or to try to use a local preprocessing statement (if false). If the driver cannot preprocess the current query successfully, it will always return to the simulated preprocessing statement.
- Can't get placeholders? Instead of a set of values, this will only get the first value to the set of data,
select * from table where userid in ( ? );
If you want to find in, you can use the Find_in_set () implementation instead:
$ids = ‘1,2,3,4,5,6‘; select * from table where find_in_set(userid, ?);
- You cannot replace a placeholder with a data table name or column name, for example:
select * from table order by ?;
- Can't get placeholders? Instead of any other SQL syntax, such as:
select extract( ? from addtime) as mytime from table;
PHP Security Programming-sql injection attack