Talking about PHP anti-injection


Some time in a certain month of a certain month, when someone reads a PHP program code, I find that somewhere will input the “direct” into the query statement. When he rushes to copy the D, he does not inject it. Point (magic_quotes_gpc is off). When he looked at the code carefully, he didn’t find the filter statement. What happened? In fact, this program uses a preliminary query technique. Why is the preparatory query technology sacred, and listening to the dangers to walk slowly to everyone.

The pre-query technique actually pre-compiles incomplete SQL statements (eg: select * from xxx where id=? “?” is a placeholder), resides in memory, and continuously substitutes data into placeholders when in use. And a technique that is implemented. The use of this technique is intended to quickly run multiple SQL statements of the same format, but since the statement has been compiled, there is no confusion between the data and the statement when the data is passed, and naturally it can prevent injection. . Pre-query technology is one of the highlights of the new MySQLi library. Before introducing the pre-query technique, let’s talk about MySQLi.

First, the operating environment

1, MySQLi library can link 4.1 (including) the above version of Mysql server.

2, MySQLi library comes with PHP5.0 (including) and above.

Second, the installation method

1, windows edit php.ini, find:; extension=php_mysqli, dII this line, remove the semicolon, save, restart apache.

2, (class) unix such as: (including but not limited to) mac os x, linux, unix, etc.

Recompile php, plus –with-mysqli=/usr/local/mysql/bin/mysql_config

Third, improvement

1.mysqli allows programmers to write code in an object-oriented way. To do this, poor php developers almost rewrite all the code and pay tribute to them.

2. The mysqli library removes some useless functions, such as: does not support persistent connections.

It can be seen that mysqli has made major improvements and is convenient for programmers. Let’s start with the preliminary query technology. The preparatory query technology requires seven links, involving six functions, which we will explain for you.

First link the MySQL server and then make a preliminary query.

1, preparation

Prototype: mysqli_stmt mysqli::prepare(string $query)

Note: $query should contain placeholders. Placeholders can take up data such as numbers, texts, etc., but they cannot occupy table names, column names, database names, etc. Among them, when placeholders occupy text, do not use quotes (for example: should be where username=?, not where username_’?’). According to the introduction just now, the statement has been compiled at this time, and naturally there will be grammar check here.

2, bind variables

Prototype: bool mysqli_stmt::bind_param(string $types, mixed &$varl[, mixed&$…]) Note: Parameter one is text type, which defines the type of each placeholder, i is an integer, d is Floating point type, s is a string type, b is a blob (for example, there are four placeholders in the preliminary query statement, the types are string type, string type, string type, integer type, then the parameter is: “sssi”). The remaining parameters correspond to the placeholders in the preliminary query in order, and the variables do not need to be defined in advance.

3, assignment

Assign a value to the variable in the second step

4, execution

Prototype: bool mysqli_stmt::execute(void)

5, the binding results

Prototype: bool mysqli_stmt::bind_result (mixed &$varl[,mied&$…])

Note: The parameters should correspond to the returned fields one by one. For queries without return data, such as delete, insert, etc., this step and the next step are not required.

6, processing data

Prototype: bool mysqli_stmt::fetch(void)

Note: This function takes no arguments. Its function is to assign the data at the pointer to the variable bound in the previous step and move the pointer down.

One line, if there is no data available at the pointer to return, the function returns false. Since there may be a lot of data, you need to use loop processing.

7, close the query

Prototype: bool mysqli_stmt::close(void)

Another point to note is that if you want to execute multiple statements, you can repeat steps 3-6, that is, reassign and then execute again.

Finally disconnected the link:

Prototype: bool mysqli::close(void)

The above is the basic theory of preliminary query, the theory has to rely on practice to test, the following two tests are tested, first introduce the test environment:

B: Safari 5.0 (6533.16) on MAC OS X10.6.4

S: Apache/2.2.15 PHP/5.3.2 mysql-5.5-m2-osx10.6-x86_64

MAC OS X10.6.4

Second, install the test program. This program was written by myself, intended to explain the meaning, to be more succinct, to make a look. See the CD for the installation method. Test below to test the first set of news systems. From the source code, the program brings the variables directly into the SQL statement, causing the injection, and the submission returns to the blank page.

Submit: http://localhost/newsl/news.php?id=1 and 1=2 union select 1,user,pass fromadmin, return the background address.

Log in to the background (http://localhost/news1/admin) with the obtained username and password.

Then test the second system. From the source code, the program uses the pre-query technique, and there is no filtering. The non-numeric part of the commit injection statement is ignored (because the bind variable is a type defined as a number), so it cannot be injected. It can be seen from the test that the preliminary query can prevent the injection attack. Such technology should attract the attention of programmers!


Leave a reply