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 patterns with code examples, and provides a step‑by‑step practical methodology for locating and confirming such flaws in an open‑source CMS project.
SQL injection remains one of the most common web security issues; although Java’s prepared statements reduce its occurrence, misuse of the MyBatis framework can still introduce serious injection risks.
MyBatis allows SQL statements to be written either as annotations or in XML files, using two parameter placeholders: # for prepared‑statement parameters and $ for direct string concatenation. For example:
<select id="queryAll" resultMap="resultMap"> SELECT * FROM NEWS WHERE ID = #{id}</select>Three typical injection scenarios in MyBatis are:
Fuzzy queries (LIKE) – developers may replace # with $ to avoid errors, leading to statements such as SELECT * FROM news WHERE title like ‘%#{title}%’. The correct approach is to use concat('%', #{title}, '%') with #.
IN clause with multiple parameters – using # inside IN (#{ids}) also fails, prompting a risky switch to $. The proper solution is to employ a <foreach> construct.
ORDER BY clause – if user‑supplied column names are concatenated with $, an attacker can inject arbitrary SQL; the safe practice is to map allowed column names on the Java side and only permit indexed values.
Practical exploitation steps using an open‑source CMS (MCMS) are demonstrated:
Import the project via IDEA from https://gitee.com/mingSoft/MCMS.git and let Maven resolve dependencies.
Search all XML files for the $ symbol (Ctrl+Shift+F) to locate potentially vulnerable statements.
Identify DAO XML files (e.g., IContentDao.xml), trace the corresponding Java interfaces and implementation classes, and follow the call chain to the front‑end controller ( McmsAction).
Observe that parameters such as categoryIds are retrieved directly via BasicUtil.getString without validation, leading to raw SQL concatenation.
Verification of the vulnerability is performed by sending a crafted request like
http://localhost:8080/ms-mcms/mcms/search.do?categoryId=1') or updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)#, which returns the MySQL version (e.g., 5.7.27), confirming successful injection.
In summary, when auditing MyBatis applications, focus on the LIKE, IN, and ORDER BY constructs, search XML files for the $ placeholder, and ensure Java‑side parameter validation to mitigate injection risks.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
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.
