SQL Injection
SQL injection is one of the most common vulnerabilities in PHP applications. In fact, it's amazing that developers have to make two errors at the same time to trigger a SQL injection vulnerability where the input data is not filtered (filtered input) and there is no escaping the data sent to the database (escaped output). These two important steps are indispensable and require special attention at the same time to reduce procedural errors.
For attackers, SQL injection attacks need to be considered and tested, and it is necessary to substantiated the database schema (assuming that the attacker does not see your source program and database schema), consider the following simple login form:
CODE:
<form action= "/login.php" method= "POST" ><p>username: <input type= "text" name= "Username"/></p ><p>password: <input type= "Password" name= "Password"/></p><p><input type= "Submit" Value= "Log in"/></p></form>
Figure 3-1 shows the form's display in the browser.
As an attacker, he starts with a query statement that presumably validates the user name and password. By looking at the source file, he can begin to guess your habits.
Figure 3-1. Display of the login form in the browser
Naming habits. It is usually assumed that the field name in your form is the same as the field name in the datasheet. Of course, ensuring that they are different is not necessarily a reliable security measure.
For the first time guess, the query in the following example is generally used:
CODE:
<?php $password _hash = MD5 ($_post[' password '); $sql = "SELECT count (*) from users WHERE username = ' {$_post[' username ']} ' and Password = ' $password _hash ' ";?>
Using the MD5 value of the user's password turns out to be a common practice, but it's not particularly safe now. Recent studies have shown that the MD5 algorithm is flawed, and that a large number of MD5 databases reduce the difficulty of MD5 reverse cracking. Please visit http://www.php.cn/to view the demo.
So, the study of Xiao, a professor at Shandong University, shows that MD5 's "collisions" can be quickly found, that is, two different files and strings that can produce the same MD5 value. MD5 is the information digest algorithm, not the encryption algorithm, the reverse crack also can not talk about. However, according to this result, in the above exception, the direct use of MD5 is dangerous.
The best way to protect it is to attach a string of your own definition to the password, for example:
CODE:
<?php $salt = ' Shiflett '; $password _hash = MD5 ($salt. MD5 ($_post[' password ']. $salt));?>
Of course, attackers may not be able to guess the first time, and they often need to do some experiments. One of the better ways to experiment is to enter single quotes as usernames, because this may expose some important information. There are a lot of developers who call function Mysql_error () to report an error when a MySQL statement executes incorrectly. See the following example:
CODE:
<?php mysql_query ($sql) or exit (Mysql_error ());?>
While this approach is useful in development, it can expose important information to attackers. If an attacker puts a single quotation mark as a user name and Mypass as a password, the query statement becomes:
CODE:
<?php $sql = "SELECT * from users WHERE username = ' and password = ' A029d0df84eb5549c641e04a9ef389e5 ' ";?>
When the statement is sent to MySQL, the system displays the following error message:
You have a error in your SQL syntax. Check themanual, corresponds to Yourmysql server version for the right syntax to Usenear ' WHERE username = ' ' Andpass Word = ' a029d0df84eb55
Effortlessly, attackers already know the two field names (username and password) and the order in which they appear in the query. In addition, the attacker knew that the data was not properly filtered (the program did not prompt for an illegal user name) and escaped (a database error occurred), and that the format of the entire where condition was exposed, so that an attacker could attempt to manipulate records that conformed to the query.
At this point, attackers have many options. One is to try to fill in a special user name, so that the query regardless of whether the user name password is consistent, can be matched:
MyUser ' or ' foo ' = ' foo '--
Assuming that Mypass is a password, the entire query becomes:
CODE:
<?php $sql = "SELECT * from users WHERE username = ' myuser ' or ' foo ' = ' foo '-- and password = ' A029d0df84eb5549c641e04a9ef389e5 ';?>
Because a SQL comment tag is inserted in the middle, the query statement is interrupted here. This allows an attacker to log in without knowing any legitimate user name and password.
If a legitimate user name is known, an attacker could log on as the user (such as Chris):
Chris '--
As long as Chris is a legitimate user name, the attacker can control the account. The reason is that the query becomes the following:
CODE:
<?php$sql = "SELECT * from users WHERE username = ' Chris '-- and password = ' A029d0df84eb5549c641e04a9ef389e5 ' ";? >
Fortunately, SQL injection is easy to avoid. As mentioned in chapter One, you must persist in filtering the input and escaping the output.
Although two steps cannot be omitted, it is possible to eliminate most of the SQL injection risk by implementing one of them. If you just filter the input without escaping the output, you are likely to encounter database errors (legitimate data may also affect the correct format of the SQL query), but this is unreliable, and legitimate data can also alter the behavior of SQL statements. On the other hand, if you escape the output without filtering the input, you can guarantee that the data will not affect the format of the SQL statement, and also prevent many common methods of SQL injection attacks.
Of course, you should stick with both steps at the same time. The way the input is filtered depends entirely on the type of input data (see the example in Chapter one), but escaping the output data used to send to the database can only be done using the same function. For MySQL users, you can use the function mysql_real_escape_string ():
CODE:
<?php $clean = Array (); $mysql = Array (); $clean [' last_name '] = "O ' Reilly"; $mysql [' Last_Name '] =mysql_real_escape_string ($clean [' last_name ']); $sql = "INSERT into user (last_name) VALUES (' {$mysql [' last_name ']} ')";?>
Try to use the escape function designed for your database. If not, using the function addslashes () is the final good method.
When all the data used to create an SQL statement is properly filtered and escaped, the risk of SQL injection is actually avoided.
CODE:
If you're using a database operation class that supports parameterized query statements and placeholders (such as pear::D b,pdo, etc.), you'll get a bit more protection. See below for an example of using pear::D B:
CODE:
<?php$sql = ' INSERT into user (last_name) ' VALUES (?) '; $DBH->query ($sql, Array ($clean [' last_name '));? >
CODE:
Because the data in the previous example does not directly affect the format of the query statement, the risk of SQL injection is reduced. PEAR::D B is automatically escaped according to your database requirements, so you only need to filter the output.
If you are using parameterized query statements, the input will only be processed as data. There is no need to escape, although you might think it is a necessary step (if you want to persist in escaping the output habit). In fact, there is essentially no impact when escaping, because there are no special characters that need to be converted. In preventing SQL injection, parameterized query statements provide powerful protection for your program.
About SQL injection, it must be said that most of the virtual host will now open the MAGIC_QUOTES_GPC option, in this case, all the client get and post data will be automatically addslashes processing, Therefore, SQL injection of string values is not feasible at this time, but to prevent SQL injection of numeric values, such as intval () and other functions for processing. But if you are writing generic software, you need to read the server's MAGIC_QUOTES_GPC and handle it accordingly.
The above is the PHP security-sql injected content, more relevant content please pay attention to topic.alibabacloud.com (www.php.cn)!