JAVA audit SQL injection

Posted by dkphp2 on Wed, 05 Jan 2022 08:34:33 +0100

0x00 Preface

Record the process of learning java audit.

0x01 JDBC mode

1. Three objects:

  • connection

    The connection object represents the database

    You can set up automatic database submission. Transaction commit (connection.commit()) and transaction rollback (connection.rollback()).

  • statement

    Call connection The createstatement () method returns a statement object.

    Is to execute sql statements

  • PreparedStatement

    The difference between the statement object and the statement object is that you do not put the SQL statement directly, but use the "statement" first? Perform precompiling as a placeholder. After precompiling is completed, perform precompiling on? After assigning and calling execute, the SQL statement can be executed without adding parameters.

Therefore, when we use JDBC, using statement to directly splice SQL statements may cause SQL injection.

2. Examples

request.getParameter("userId")

private String getNameByUserId(String userId) {
    Connection conn = getConn();//Get connection
    String sql = "select name from user where id=" + userId;
    Statement stmt =  conn.createStatement();
    ResultSet rs=stmt.executeUpdate(sql);
}

The above code is not precompiled, and then directly splices the parameters obtained in the previous paragraph to the sql statement for execution, which will produce sql injection;

Here is another example:

request.getParameter("userId")

private String getNameByUserId(String userId) {
    Connection conn = getConn();//Get connection
    String sql = "select name from user where id=" + userId;
    PreparedStatement pstmt =  conn.prepareStatement(sql);
    ResultSet rs=pstmt.executeUpdate();
}

In this way, although PreparedStatement is used, precompiling is not standardized, and the same splicing method will also cause sql injection problems;

The following is the method of precompiling of the specification:

//Safe, precompiled, preventing sql injection
Connection conn = getConn();//Get connection
String sql = "select id, username, password, role from user where id=?"; //The statement will be precompiled before executing sql
PreparedStatement pstmt = conn.prepareStatement(sql); 
pstmt.setString(1, id); 
ResultSet rs=pstmt.executeUpdate();

0x02 Mybatis

Mybatis review

  • maven configuration for mybatis

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    
  • config.xml configuration database connection file

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <environments default="dev">
            <environment id="dev">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <property name="url"
                              value="jdbc:mysql://localhost:3306/mybatistest"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="UserMapper.xml"/>
        </mappers>
    </configuration>
    

    Mainly pay attention to the xml registered in the configuration file. There are two ways to obtain values, namely ${} and #{}.

    difference:

    "#{}" treat the incoming data as a string, and add a double quotation mark to the automatically incoming data, which belongs to the correct precompiling, and all the input parameters will become part of the query;

    "${}" directly splices the incoming data into sql, resulting in sql injection. For example, where username={username}, if the value passed in is 111, the value when parsing into sql is where username=111; If the value passed in is 1 and 1=1;, The parsed sql is: select id, username, password, role from user where username=1 and 1=1.

MyBatis is prone to three problems

1. like fuzzy query

Use like for fuzzy query in Mybatis:

Select * from news where title like '%#{title}%'

However, this way of writing will report errors and throw exceptions. At this time, changing # to $can work normally, but it also produces security problems;

Correct writing:

select * from news where tile like concat('%',#{title}, '%')

2. Multiple parameters after in

An error will be reported when using # multiple IDS after in

Select * from news where id in (#{ids})

The correct usage is to use foreach instead of # simply replacing it with$

id in<foreach collection="ids" item="item" open="("separatosr="," close=")">#{ids} </foreach>

3. After order by

Select * from news where title ='#{titlename}' order by #{time} asc

It should be noted that after order by is # executed, an error will also be reported. Precompiled cannot be used when using order by statement. The reason is that the field name or field position needs to be added after the order by clause, and the field name cannot be quoted. Otherwise, it will be considered as a string rather than a field name. However, using preparestatement will force the parameter to add ', Therefore, we should be prepared for defense in filtering

Correct writing:

Select * from news where title ='#{titlename}' order by ${time} asc

Therefore, we can observe these problems during the audit.

Summary: you can use idea to search for the $keyword. First filter the xml file to search for $, and analyze it one by one. Pay special attention to the order by injection of mybatis generator. The global search calls out Find in Path, filter the suffix xml, search for the $keyword, find the database file that is mybatis, find the calling function, and ⌘ + f7 view the call chain to check whether the middle is filtered

reference resources

https://www.cnblogs.com/CoLo/p/15225346.html

https://www.cnblogs.com/nice0e3/p/13647511.html

https://zeo.cool/2020/07/24/java Self study of code audit: sql injection/

https://xz.aliyun.com/t/10686

https://cloud.tencent.com/developer/article/1123127