Precautions for mybatis to prevent sql injection

1. The principle of sql injection

     When entering page parameters, enter a string with grammatical meaning, which can change your original SQL.

E.g:

  1. <?php    
  2. $username = "aaa";    
  3. $pwd = "pwd";    
  4. $sql = "SELECT * FROM table WHERE username = '{$username}' AND pwd = '{$pwd}'";    
  5. echo $sql; //输出  SELECT * FROM table WHERE username = 'aaa' AND pwd = 'pwd'    
  6. ?>   

Malicious users use the or keyword to inject SQL without knowing the password.

  1. <?php    
  2. $username = "aaa";    
  3. $pwd =  "fdsafda' or '1'='1"; //The previous password was filled in blindly.. Later, the or keyword was used.      
  4. $sql = "SELECT * FROM table WHERE username = '{$username}' AND pwd = '{$pwd}'";    
  5. echo $sql;  //输出  SELECT * FROM table WHERE username = 'aaa' AND pwd = 'fdsafda' or '1'='1'    
  6. ?>   

2. The principle of preventing sql

Divide the execution of the sql statement into two parts

   The first step: first send the sql without parameters to the database for pre-compilation.

   Step 2: Send the parameters and precompiled sql to the database for execution.

                Because: SQL injection will only affect the SQL pre-compilation stage, regardless of the syntax keywords in the parameters during execution.

     Note: How does MyBatis do SQL precompile? In fact, at the bottom of the framework, the PreparedStatement class in JDBC is at work. PreparedStatement is a subclass of Statement that we are familiar with. Its object contains compiled SQL statements. This "prepared" approach not only improves security, but also improves efficiency when executing the same SQL multiple times. The reason is that the SQL is already compiled and does not need to be compiled again when executing it again.

E.g:

<select id="getBlogById" resultType="Blog" parameterType=”int”>

         SELECT id,title,author,content

         FROM blog

WHERE id=#{id}

</select>

 

Here, parameterType represents the input parameter type, and resultType represents the output parameter type. In response to the above, if we want to prevent SQL injection, of course we have to work on input parameters. The yellow highlight in the above code is the part where the input parameters are spliced ​​in SQL. After passing in the parameters, print out the executed SQL statement, and you will see that the SQL is like this:

SELECT id,title,author,content FROM blog WHERE id = ?

No matter what parameters are entered, the printed SQL is like this. This is because MyBatis enables the pre-compilation function. Before the SQL is executed, the above SQL will be sent to the database for compilation; when executing, the compiled SQL can be used directly, and the placeholder "?" can be replaced. Because SQL injection can only work on the compilation process, this way can well avoid the problem of SQL injection.


But pay attention to one detail

#{}:相当于JDBC中的PreparedStatement

${}:是输出变量的值,没有防止sql注入,需要自己通过技术手段过滤参数来防止sql注入。

例如:同样的sql语句只要把 #{id} 变成 ${id}就不能防止sql注入了。

<select id="getBlogById" resultType="Blog" parameterType=”int”>

         SELECT id,title,author,content

         FROM blog

WHERE id=${id}

</select>

打印出执行的SQL语句,会看到SQL是这样的:

SELECT id,title,author,content FROM blog WHERE id = 3

  参数和语句一起编译的不能,没有采用jdbc的参数绑定方式。



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324601310&siteId=291194637