Mybatis is how to achieve the anti-SQL injection

In many Mybatis with daily development framework, such as the interview is often a problem: $and #difference, the difference between them is the use #can prevent SQL injection, it is today a look at how SQL injection.

What is SQL Injection

Before we discuss how to realize, first of all look at what is SQL injection, we have a simple query: query information based on a user id. It sql statement should look like this: select * from user where id =. We fill in the id query based on the incoming condition.

If normal operation, passing in a normal id, such as 2, then this statement becomes select * from user where id =2. This statement can be run properly and in line with our expectations.

But if the argument passed to become '' or 1=1, then this statement becomes select * from user where id = '' or 1=1. Let us think about this statement of the results would be how? It will list all of our users query data out, obviously this is a big mistake. This is the SQL injection.

How to prevent SQL injection Mybatis

Talked about at the beginning, it can be used #to prevent SQL injection, it's written as follows:

<select id="safeSelect" resultMap="testUser">
   SELECT * FROM user where id = #{id}
</select>

In mybatis there is a written query is to use $, it's written as follows:

<select id="unsafeSelect" resultMap="testUser">
   select * from user where id = ${id}
</select>

As we continue to call on the outside of these two methods, we found that if the security parameters passed, the two results are not different, if the parameter passed in unsafe, the first to use #the method can not find the results ( select * from user where id = '' or 1=1) , but the second parameter is $under'll get all the results.

And if we sql print, you will find added #, the execution of the sql database: select * from user where id = ' \'\' or 1=1 'it will add a layer of quotation marks outside our parameters, in use $, it's the implementation of sql injection select * from user where id = '' or 1=1.

Abandoned $okay

We use #also can be completed $role, and use $there is a danger, then we do not use in the future $is not on line yet.

Not, it's just that we have in this scenario problem, but there are still an irreplaceable role in some scene dynamic query, for example, to dynamically modify the table name select * from ${table} where id = #{id}. We can dynamically change the query table in case of return consistent information, which is mybatis powerful dynamic place.

How to implement SQL injection, do not realize how Mybatis

In fact Mybatis also connected to a database through jdbc, if we look at the use of jdbc, you can get for this reason.

#Used PreparedStatementfor pretreatment, and then set the manner set by the placeholder, and $is through Statementthe query result directly query When splicing parameters.

So we can use jdbc to implement SQL injection.

Look at these two codes:

public static void statement(Connection connection) {
  System.out.println("statement-----");
  String selectSql = "select * from user";
  // 相当于mybatis中使用$,拿到参数后直接拼接
  String unsafeSql = "select * from user where id = '' or 1=1;";
  Statement statement = null;
  try {
    statement = connection.createStatement();
  } catch (SQLException e) {
    e.printStackTrace();
  }
  try {
    ResultSet resultSet = statement.executeQuery(selectSql);
    print(resultSet);
  } catch (SQLException e) {
    e.printStackTrace();
  }
  System.out.println("---****---");
  try {
    ResultSet resultSet = statement.executeQuery(unsafeSql);
    print(resultSet);
  } catch (SQLException e) {
    e.printStackTrace();
  }
}

public static void preparedStatement(Connection connection) {
  System.out.println("preparedStatement-----");
  String selectSql = "select * from user;";
  //相当于mybatis中的#,先对要执行的sql进行预处理,设置占位符,然后设置参数
  String safeSql = "select * from user where id =?;";
  PreparedStatement preparedStatement = null;
  try {
    preparedStatement = connection.prepareStatement(selectSql);
    ResultSet resultSet = preparedStatement.executeQuery();
    print(resultSet);
  } catch (SQLException e) {
    e.printStackTrace();
  }
  System.out.println("---****---");
  try {
    preparedStatement = connection.prepareStatement(safeSql);
    preparedStatement.setString(1," '' or 1 = 1 ");
    ResultSet resultSet = preparedStatement.executeQuery();
    print(resultSet);
  } catch (SQLException e) {
    e.printStackTrace();
  }
}

public static void print(ResultSet resultSet) throws SQLException {
  while (resultSet.next()) {
    System.out.print(resultSet.getString(1) + ", ");
    System.out.print(resultSet.getString("name") + ", ");
    System.out.println(resultSet.getString(3));
  }
}

to sum up

  • Mybatis use #can be prevented SQL injection, $does not prevent SQL injection
  • Mybatis The principle is called SQL injection in jdbc PreparedStatementto pretreatment.

    This article from the blog article multiple platforms OpenWrite release!
    Bloggers E-mail: [email protected], there are problems you can mail exchange.

Guess you like

Origin www.cnblogs.com/lnj96/p/12157911.html