浅谈MyBatis Example模式SQL注入风险

 更新时间:2025年10月31日 09:00:25   作者:就叫飞六吧  
在使用MyBatis逆向工程生成的Example查询模式时,很多开发者看到XML中存在${}占位符就会担心SQL注入问题,本文就来介绍一下MyBatis Example模式SQL注入风险,感兴趣的可以了解一下

在使用MyBatis逆向工程生成的Example查询模式时,很多开发者看到XML中存在${}占位符就会担心SQL注入问题。但实际上,存在${}并不等同于存在SQL注入风险。本文将详细分析何时会存在真正的注入风险。

存在SQL注入的两个关键前提

前提一:Criteria存在自定义扩展且接受外部输入

MyBatis Generator生成的标准Criteria类是相对安全的,但如果开发者添加了自定义扩展方法,就可能引入风险:

// 危险的自定义扩展示例
public class MTaxSbPayExample {
    public static class Criteria extends GeneratedCriteria {
        
        // ❌ 危险:允许用户直接传入SQL条件
        public Criteria andCustomCondition(String sqlCondition, Object value) {
            addCriterion(sqlCondition, value, "custom");
            return (Criteria) this;
        }
        
        // ❌ 危险:动态表名或列名
        public Criteria andDynamicColumn(String columnName, String operator, Object value) {
            addCriterion(columnName + " " + operator, value, columnName);
            return (Criteria) this;
        }
    }
}

如果用户输入直接传递给这些方法:

// 恶意输入示例
String userInput = "1=1; DROP TABLE users;--";
example.createCriteria().andCustomCondition(userInput, "someValue");

前提二:Example对象作为接口参数且orderByClause被不当赋值

另一个风险点是orderByClause字段,因为ORDER BY子句通常需要使用${}来处理列名:

<if test="orderByClause != null">
  order by ${orderByClause}
</if>

危险场景:

// ❌ 危险:直接将用户输入作为排序条件
@RestController
public class DataController {
    
    public List<MTaxSbPay> getData(@RequestParam String sortBy) {
        MTaxSbPayExample example = new MTaxSbPayExample();
        // 直接使用用户输入,存在注入风险
        example.setOrderByClause(sortBy);  
        return mapper.selectByExample(example);
    }
}

恶意请求:

GET /getData?sortBy=id; DROP TABLE users;--

为什么存在${}不一定有SQL注入风险

1. 硬编码的安全使用

在标准的MyBatis Generator实现中,${criterion.condition}中的condition是硬编码的:

// 生成的安全方法
public Criteria andIdEqualTo(String value) {
    addCriterion("ID =", value, "id");  // "ID =" 是硬编码字符串
    return (Criteria) this;
}

对应的XML处理:

<when test="criterion.singleValue">
  and ${criterion.condition} #{criterion.value}
</when>

最终生成安全的SQL:

WHERE ID = ?  -- 参数: 用户输入值

2. 参数分离的设计模式

MyBatis Generator采用了条件与参数分离的设计:

  • 条件部分${criterion.condition}):硬编码的操作符,如=>LIKE
  • 参数部分#{criterion.value}):用户输入,通过参数化查询处理

这种设计确保了即使使用${},也不会直接拼接用户输入的内容。

3. 用户输入路径受限

标准的Criteria类只提供预定义的方法:

// 用户只能通过这些安全的方法构建查询
criteria.andIdEqualTo(userInput);      // 安全
criteria.andNameLike("%" + userInput + "%");  // 安全  
criteria.andStatusIn(Arrays.asList("ACTIVE", "INACTIVE"));  // 安全

用户无法直接控制criterion.condition的值,只能影响criterion.value,而后者是参数化处理的。

总结

MyBatis的${}占位符本身并不等同于SQL注入漏洞。关键在于:

  • 数据来源:是硬编码还是用户输入?
  • 使用方式:是否进行了适当的验证和过滤?
  • 设计模式:是否采用了参数分离的安全设计?

标准的MyBatis Generator生成的Example代码通常是安全的,真正的风险往往来自于开发者的不当扩展和使用。

到此这篇关于浅谈MyBatis Example模式SQL注入风险的文章就介绍到这了,更多相关MyBatis Example模式SQL注入内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Idea连接数据库并执行SQL语句的方法示例

    Idea连接数据库并执行SQL语句的方法示例

    这篇文章主要介绍了Idea连接数据库并执行SQL语句的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • 关于QueryWrapper,实现MybatisPlus多表关联查询方式

    关于QueryWrapper,实现MybatisPlus多表关联查询方式

    这篇文章主要介绍了关于QueryWrapper,实现MybatisPlus多表关联查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教。
    2022-01-01
  • SWT(JFace)体验之ApplicationWindow

    SWT(JFace)体验之ApplicationWindow

    SWT(JFace)体验之ApplicationWindow
    2009-06-06
  • SpringBoot中使用MyBatis-Plus详细步骤

    SpringBoot中使用MyBatis-Plus详细步骤

    MyBatis-Plus是MyBatis的增强工具,简化了MyBatis的使用,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • SWT(JFace)体验之StackLayout布局

    SWT(JFace)体验之StackLayout布局

    SWT(JFace)体验之StackLayout布局实现代码。
    2009-06-06
  • java开发CPU流水线与指令乱序执行详解

    java开发CPU流水线与指令乱序执行详解

    这篇文章主要为大家介绍了java开发CPU流水线与指令乱序执行详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • SpringBoot RestTemplate GET POST请求的实例讲解

    SpringBoot RestTemplate GET POST请求的实例讲解

    这篇文章主要介绍了SpringBoot RestTemplate GET POST请求的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 如何在Java中优雅地使用正则表达式详解

    如何在Java中优雅地使用正则表达式详解

    这篇文章主要给大家介绍了关于如何在Java中优雅地使用正则表达式的相关资料,正则表达式就是一个字符串,但和普通的字符串不同的是,正则表达式是对一组相似字符串的抽象,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-02-02
  • SpringBoot整合mybatisplus和druid的示例详解

    SpringBoot整合mybatisplus和druid的示例详解

    这篇文章主要介绍了SpringBoot整合mybatisplus和druid的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-08-08
  • Java的反射机制一起来看看

    Java的反射机制一起来看看

    这篇文章主要为大家详细介绍了Java反射机制,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03

最新评论