Mitigation Strategy: Parameterized Queries (Prefer over ${}
)
-
Mitigation Strategy:
#{}
Parameterized Queries (Prefer over${}
)-
Description:
- Identify all SQL statements: Examine all MyBatis mapper XML files (
.xml
). Locate all<select>
,<insert>
,<update>
, and<delete>
tags. - Analyze dynamic SQL: Within each SQL statement, identify any parts that are dynamically generated based on input (e.g.,
WHERE
clauses,ORDER BY
clauses, table names, column names). - Replace
${}
with#{}
: Wherever possible, replace direct string substitution (${}
) with parameterized queries (#{}
).#{}
tells MyBatis to treat the value as a parameter, which will be properly escaped by the underlying JDBC driver. - Use
<bind>
for complex expressions: If you need to perform string concatenation or other operations before passing the value to the query, use the<bind>
element to create a new variable within the MyBatis context. This keeps the logic within MyBatis and allows it to handle escaping. Example:<select id="findUsersByName" resultType="User"> <bind name="pattern" value="'%' + _parameter + '%'" /> SELECT * FROM users WHERE username LIKE #{pattern} </select>
- Test thoroughly: After making changes, thoroughly test the application to ensure that the queries still function correctly and that no SQL injection vulnerabilities are present. Use a variety of inputs, including potentially malicious ones.
- Identify all SQL statements: Examine all MyBatis mapper XML files (
-
Threats Mitigated:
- SQL Injection (Severity: Critical): Direct string substitution (
${}
) allows attackers to inject arbitrary SQL code, potentially leading to data breaches, data modification, or even complete system compromise.#{}
prevents this by treating input as data, not code. - Second-Order SQL Injection (Severity: Critical): Even if data is initially sanitized, if it's later used in a dynamic SQL statement with
${}
, it could still be vulnerable.#{}
mitigates this risk.
- SQL Injection (Severity: Critical): Direct string substitution (
-
Impact:
- SQL Injection: Risk reduction: Very High (near elimination if used consistently).
#{}
is the primary defense against SQL injection in MyBatis. - Second-Order SQL Injection: Risk reduction: Very High.
- SQL Injection: Risk reduction: Very High (near elimination if used consistently).
-
Currently Implemented:
- Mapper XML files:
userMapper.xml
,productMapper.xml
(mostly implemented, some${}
usage remains inorderMapper.xml
). - Java code interacting with mappers: Generally uses parameterized methods.
- Mapper XML files:
-
Missing Implementation:
orderMapper.xml
: Contains several instances of${}
for dynamicORDER BY
clauses. These need to be refactored to use#{}
or a safe alternative (see below).- Dynamic table name selection in
reportService.java
: Currently uses string concatenation to build the table name. This needs to be addressed (see "Dynamic Table/Column Names" mitigation below).
-
Mitigation Strategy: Safe Dynamic ORDER BY
and LIMIT
(MyBatis-Specific Handling)
-
Mitigation Strategy: Safe Dynamic
ORDER BY
andLIMIT
(MyBatis-Specific Handling)-
Description:
- Identify
ORDER BY
andLIMIT
clauses: Locate all dynamicORDER BY
andLIMIT
clauses in your mapper XML files. - Whitelist approach (for
ORDER BY
within MyBatis): While the safest approach involves whitelisting in your Java service layer before calling MyBatis, you can implement a limited form of whitelisting within the MyBatis XML using<choose>
,<when>
, and<otherwise>
:This approach is less flexible than a Java-side whitelist but is far safer than using<select id="findUsers" resultType="User"> SELECT * FROM users ORDER BY <choose> <when test="orderBy == 'username'">username</when> <when test="orderBy == 'creation_date'">creation_date</when> <otherwise>id</otherwise> <!-- Default sort column --> </choose> <if test="orderDirection != null"> <choose> <when test="orderDirection == 'ASC'">ASC</when> <when test="orderDirection == 'DESC'">DESC</when> <otherwise>ASC</otherwise> </choose> </if> </select>
${}
directly with user input. TheorderBy
andorderDirection
variables would still be passed in from Java, but their values are now constrained within the XML. - Parameterize
LIMIT
andOFFSET
: Always use#{}
forLIMIT
andOFFSET
values. These are often controlled by user input (e.g., pagination). This is a direct MyBatis interaction. - MyBatis Timeout Configuration: Set
timeout
attribute in your statements.<select id="findUsers" resultType="User" timeout="10"> ... </select>
- Identify
-
Threats Mitigated:
- SQL Injection (Severity: Critical): Attackers could inject malicious SQL into
ORDER BY
orLIMIT
clauses. - Denial of Service (Severity: High): An attacker could provide a very large
LIMIT
value or a complexORDER BY
that causes performance issues.
- SQL Injection (Severity: Critical): Attackers could inject malicious SQL into
-
Impact:
- SQL Injection: Risk reduction: High (using the
<choose>
approach within MyBatis). Very High if combined with Java-side whitelisting. - Denial of Service: Risk reduction: High (by limiting the
LIMIT
value and setting timeouts).
- SQL Injection: Risk reduction: High (using the
-
Currently Implemented:
LIMIT
andOFFSET
are generally parameterized using#{}
.- No timeout configuration
-
Missing Implementation:
orderMapper.xml
:ORDER BY
is still handled using${}
. The<choose>
approach (or a Java-side whitelist) needs to be implemented.- Timeout configuration in all mappers.
-
Mitigation Strategy: Dynamic Table/Column Names (MyBatis-Specific Handling)
-
Mitigation Strategy: Dynamic Table/Column Names (MyBatis-Specific Handling)
-
Description:
- Identify dynamic table/column names: Locate any instances where table names or column names are dynamically generated based on input within your MyBatis XML mappers.
- Whitelist approach (Strongly Recommended, often best done outside MyBatis): Ideally, handle whitelisting in your Java service layer. However, if you must handle it within MyBatis, use the
<choose>
,<when>
,<otherwise>
structure, similar to theORDER BY
example above. This is less ideal than Java-side whitelisting because it can become complex and harder to maintain.<select id="getData" resultType="MyData"> SELECT <choose> <when test="columnName == 'col1'">col1</when> <when test="columnName == 'col2'">col2</when> <otherwise>default_col</otherwise> </choose> FROM <choose> <when test="tableName == 'table1'">table1</when> <when test="tableName == 'table2'">table2</when> <otherwise>default_table</otherwise> </choose> </select>
- Avoid
${}
: Absolutely avoid using${}
for dynamic table/column names with any input that could be influenced by a user. Even with the<choose>
approach, ensure the variables passed to the mapper come from a trusted source.
-
Threats Mitigated:
- SQL Injection (Severity: Critical): Dynamic table/column names are a high-risk area for SQL injection.
- Information Disclosure (Severity: Medium): An attacker might be able to probe for the existence of tables or columns.
-
Impact:
- SQL Injection: Risk reduction: High (with the
<choose>
approach within MyBatis, but ideally handled in Java). - Information Disclosure: Risk reduction: Moderate.
- SQL Injection: Risk reduction: High (with the
-
Currently Implemented:
- No consistent approach is currently implemented.
-
Missing Implementation:
reportService.java
: Uses string concatenation to build table names dynamically. This needs to be refactored, ideally to use a whitelist in Java, and then pass a safe table name to MyBatis.dynamicColumnMapper.xml
: Uses${}
for dynamic column names. This needs to be refactored to use the<choose>
approach (or, preferably, a Java-side whitelist).
-
Mitigation Strategy: Disable DTDs (XXE Prevention - MyBatis Configuration)
-
Mitigation Strategy: Disable DTDs (XXE Prevention - MyBatis Configuration)
-
Description:
- Locate
SqlSessionFactory
creation: Find the code where theSqlSessionFactory
is created (usually in a configuration class). - Set the
disableDtd
property: Add the following code to disable DTDs:This should be done before building theconfiguration.setVariables(new Properties() {{ setProperty("org.apache.ibatis.parsing.xml.disableDtd", "true"); }});
SqlSessionFactory
. This is a direct configuration change to MyBatis. - Verify custom
XMLMapperEntityResolver
(if any): If you have a customXMLMapperEntityResolver
, ensure it does not load external entities. The defaultXMLMapperEntityResolver
is generally safe. This is a direct check of a MyBatis component.
- Locate
-
Threats Mitigated:
- XML External Entity (XXE) Injection (Severity: Critical): XXE attacks can allow attackers to read local files, access internal network resources, or cause a denial of service.
-
Impact:
- XXE Injection: Risk reduction: Very High (eliminates the vulnerability if DTDs are not required).
-
Currently Implemented:
- Not explicitly implemented.
-
Missing Implementation:
- The
disableDtd
property should be explicitly set in theSqlSessionFactory
configuration (MyBatisConfig.java
).
- The
-
Mitigation Strategy: Secure Logging (MyBatis-Specific Configuration)
-
Mitigation Strategy: Secure Logging (MyBatis-Specific Configuration)
-
Description:
- Identify logging configuration: Locate your logging configuration files (e.g.,
logback.xml
,log4j2.xml
). - Set appropriate log levels for MyBatis: In production environments, set the logging level for MyBatis specifically to
WARN
orERROR
. This prevents sensitive SQL queries and parameters from being logged by MyBatis. UseDEBUG
orTRACE
only in development or testing environments.This directly controls MyBatis' logging behavior.<!-- Example for Logback --> <logger name="org.apache.ibatis" level="WARN" /> <logger name="your.package.mappers" level="WARN" />
- Identify logging configuration: Locate your logging configuration files (e.g.,
-
Threats Mitigated:
- Information Disclosure (Severity: Medium): Exposure of sensitive data (e.g., passwords, API keys) in logs generated by MyBatis.
-
Impact:
- Information Disclosure: Risk reduction: High (if logging is configured correctly).
-
Currently Implemented:
- Log levels are set to
INFO
in the production environment, which is too verbose.
- Log levels are set to
-
Missing Implementation:
- The log level for MyBatis and mapper packages needs to be changed to
WARN
inlogback.xml
(production profile).
- The log level for MyBatis and mapper packages needs to be changed to
-
Mitigation Strategy: Regular Updates (of MyBatis)
-
Mitigation Strategy: Regular Updates (of MyBatis)
-
Description:
- Check for updates: Regularly check the MyBatis website or GitHub repository for new releases.
- Review release notes: Read the release notes for each new version to see if any security vulnerabilities have been fixed in MyBatis itself.
- Update dependencies: Update the MyBatis dependency in your project's build file (e.g.,
pom.xml
for Maven,build.gradle
for Gradle). This directly updates the MyBatis library. - Test: Thoroughly test the application after updating MyBatis to ensure that there are no regressions.
-
Threats Mitigated:
- Known Vulnerabilities (Severity: Varies): Vulnerabilities discovered and fixed in newer versions of MyBatis.
-
Impact:
- Known Vulnerabilities: Risk reduction: High (prevents exploitation of known vulnerabilities in MyBatis).
-
Currently Implemented:
- No formal process for regular updates is in place.
-
Missing Implementation:
- A process needs to be established to regularly check for and apply MyBatis updates.
-