MyBatis SQL Injection Auditing: Common Vulnerabilities and Practical Analysis
This article explains how SQL injection can still occur in Java applications using MyBatis, describes the three typical vulnerable patterns (LIKE, IN, ORDER BY), and provides a step‑by‑step practical workflow—including code snippets and verification—to help beginners audit and remediate such issues.
Introduction SQL injection remains one of the most common web security issues. Although MyBatis and other ORM frameworks reduce the risk by encouraging prepared statements, improper use can still introduce vulnerabilities. This guide uses a MyBatis‑based Java web application as a concrete example to show beginners how to discover and exploit such flaws.
1. MyBatis SQL Injection Patterns MyBatis supports two parameter placeholders in XML: # (prepared statement) and $ (string concatenation). The following three patterns are prone to injection:
1) Fuzzy query (LIKE)
<select id="queryAll" resultMap="resultMap">
SELECT * FROM NEWS WHERE ID = #{id}
</select>Using $ instead of # in a LIKE clause allows arbitrary input to be concatenated, leading to injection. The correct approach is to keep # and build the pattern with concat('%', #{title}, '%').
2) IN clause with multiple parameters Select * from news where id in (#{ids}) Replacing # with $ causes the same issue. The proper solution is to use MyBatis <foreach> to safely iterate over the collection.
3) ORDER BY clause If the column name is taken directly from user input, an attacker can inject arbitrary SQL. The safe practice is to map allowed column names to an index or whitelist on the Java side. Note that MyBatis‑generator may generate $ for ORDER BY, which requires extra scrutiny.
2. Practical Auditing Workflow The author analyzes an open‑source CMS (https://gitee.com/mingSoft/MCMS.git) using the following steps:
Import the project into IntelliJ IDEA via “Get from Version Control”.
Search all .xml files for the $ placeholder (Ctrl+Shift+F, filter by *.xml).
Identify suspicious statements (e.g., those using LIKE, IN, or ORDER BY) and trace the corresponding DAO methods.
Locate the Java mapping methods (e.g., IContentDao.java, IContentDaoImpl.java) and follow the call chain to the controller ( McmsAction.java).
Inspect utility methods such as BasicUtil.getString and SpringUtil.getRequest() that forward raw parameters to the SQL layer.
Confirm the vulnerability by sending a crafted request, e.g., 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 and Recommendations 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 ensure Java‑side validation of all user‑supplied values. Treat every input as potentially malicious and enforce strict parameter checks to prevent future attacks.
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
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
