MyBatis SQL Injection Auditing: Common Pitfalls and Practical Analysis

This article explains how improper use of MyBatis in Java web applications can lead to SQL injection vulnerabilities, illustrates three typical injection scenarios with code examples, and provides a step‑by‑step practical workflow for discovering and confirming such flaws in a real CMS project.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
MyBatis SQL Injection Auditing: Common Pitfalls and Practical Analysis

SQL injection remains one of the most common web security issues, and although prepared statements and ORM frameworks reduce its occurrence, misusing MyBatis can still introduce vulnerabilities.

1. MyBatis SQL Injection

MyBatis allows SQL statements to be written either as annotations or in XML files. When writing XML, two parameter placeholders are supported: # (safe) and $ (unsafe). The following example shows a simple select using #:

<select id="queryAll" resultMap="resultMap"> SELECT * FROM NEWS WHERE ID = #{id}</select>

Three typical misuse patterns can cause injection:

1) Fuzzy query (LIKE)

Select * from news where title like ‘%#{title}%’

Developers sometimes replace # with $ to avoid errors, which makes the query vulnerable. The correct approach is to keep # and concatenate the wildcard on the Java side, e.g.:

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

2) Multiple parameters after IN

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

Using # here also fails; the proper solution is to use MyBatis <foreach> to iterate over the collection:

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

3) ORDER BY clause

For dynamic ORDER BY, the field name should be validated against a whitelist in the Java layer, because MyBatis‑generator may generate $ for ORDER BY, which can be exploited.

2. Practical Auditing Workflow

The author used an open‑source CMS to demonstrate the audit process:

Import the project into IntelliJ IDEA via Get from Version Control using the repository URL.

Search for the $ symbol in XML files (Ctrl+Shift+F, filter by *.xml) to locate potentially unsafe statements.

Identify suspicious statements (e.g., those using IN or concatenated strings) and trace the corresponding DAO interfaces and implementation classes.

Follow the call chain from the DAO to the controller (e.g., McmsAction) to see how user input reaches the SQL.

Confirm the vulnerability by sending a crafted request such as

http://localhost:8080/ms-mcms/mcms/search.do?categoryId=1') or updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)#

, which returns the MySQL version, proving injection.

3. Summary

When auditing MyBatis applications, focus on three areas: LIKE, IN, and ORDER BY. Search XML files for the $ placeholder, pay special attention to code generated by MyBatis‑generator, and always validate or sanitize user‑supplied values in the Java layer.

1. In MyBatis, audit SQL injection by concentrating on LIKE, IN, and ORDER BY. 2. When writing SQL in XML, search for $ and examine each occurrence, especially in MyBatis‑generator output. 3. Annotation‑based SQL follows the same principles. 4. Perform thorough parameter checks in Java, assuming all user input may be malicious.
JavaMyBatissecuritySQL InjectionCode Auditing
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.