baomidou/mybatis-plus · error · MybatisPlusException
Discovering SQL injection column: %s
Error message
Discovering SQL injection column: %s
What it means
UpdateWrapper.checkSqlInjection() opted this wrapper into SQL-injection screening, and a column string used in set/eq/condition building matched known injection patterns in SqlInjectionUtils. The wrapper rejects the value before the SQL reaches the database.
Source
Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/update/UpdateWrapper.java:90
/**
* 检查 SQL 注入过滤
*/
private boolean checkSqlInjection;
/**
* 开启检查 SQL 注入
*/
public UpdateWrapper<T> checkSqlInjection() {
this.checkSqlInjection = true;
return this;
}
@Override
protected String columnToString(String column) {
if (checkSqlInjection && SqlInjectionUtils.check(column)) {
throw new MybatisPlusException("Discovering SQL injection column: " + column);
}
return column;
}
@Override
public String getSqlSet() {
if (CollectionUtils.isEmpty(sqlSet)) {
return null;
}
return String.join(Constants.COMMA, sqlSet);
}
@Override
public UpdateWrapper<T> set(boolean condition, String column, Object val, String mapping) {
return maybeDo(condition, () -> {
String sql = formatParam(mapping, val);
sqlSet.add(column + Constants.EQUALS + sql);
});View on GitHub (pinned to bf67d90747)
Solutions
- Use the two-argument form set("status", value) instead of embedding expressions in the column string
- Whitelist any dynamic column names coming from external input
- For legitimate identifiers flagged by the checker, apply proper DB identifier quoting rather than bypassing the check
Example fix
// before
uw.checkSqlInjection().set("name='a', role='admin'", null);
// after
uw.checkSqlInjection().set("name", "a").set("role", "admin"); Defensive patterns
Strategy: validation
Validate before calling
private static final Set<String> UPDATABLE = Set.of("name", "email", "status");
UpdateWrapper<User> uw = new UpdateWrapper<>().checkSqlInjection();
if (UPDATABLE.contains(field)) uw.set(field, value); else throw new IllegalArgumentException("Field not updatable: " + field); Try / catch
try { uw.set(col, val); } catch (MybatisPlusException e) { audit.warn("Rejected set column {}", col); throw new BadRequestException("Invalid field"); } Prevention
- Use set(column, value) — never concatenate expressions into the column string
- Whitelist any externally influenced column names
- Reserve checkSqlInjection-off wrappers for fully internal, constant SQL
When it happens
Trigger: Calling updateWrapper.checkSqlInjection() and then passing a suspicious string as a column argument, e.g. set("name = 'x', role = 'admin'", value), or column strings built from raw request input.
Common situations: Using UpdateWrapper.set with a combined 'col = expr' string instead of set(column, value); front-end driven field names flowing into update conditions; test data containing quotes/semicolons used as a column name.
Related errors
- Discovering SQL injection column: %s
- %s already contains value for %s
- %s does not contain value for %s
- %s is ambiguous in %s (try using the full name including the
- Should be specified either value() or name() attribute in th
AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14).
Data as JSON: /api/errors/1d8559aec395795b.
Report an issue: GitHub.