RuoYi SQL注入:MyBatis防注入策略深度解析

RuoYi SQL注入:MyBatis防注入策略深度解析

【免费下载链接】RuoYi 🎉 基于SpringBoot的权限管理系统 易读易懂、界面简洁美观。 核心技术采用Spring、MyBatis、Shiro没有任何其它重度依赖。直接运行即可用 【免费下载链接】RuoYi 项目地址: https://gitcode.com/yangzongzhuan/RuoYi

引言:SQL注入的安全威胁

SQL注入(SQL Injection)是Web应用中最常见且危害极大的安全漏洞之一。攻击者通过在用户输入中注入恶意SQL代码,可以绕过应用程序的安全机制,直接操作数据库,导致数据泄漏、数据篡改甚至服务器被控制等严重后果。

在RuoYi这样基于SpringBoot的权限管理系统中,数据库安全尤为重要。本文将深入分析RuoYi框架中MyBatis的SQL注入防护策略,帮助开发者构建更加安全可靠的企业级应用。

MyBatis防注入机制解析

1. 参数化查询(Prepared Statements)

MyBatis通过预编译语句(Prepared Statements)机制有效防止SQL注入。当使用#{}占位符时,MyBatis会将参数安全地传递给数据库驱动程序,而不是直接拼接SQL字符串。

// 安全的参数化查询示例
@Select("SELECT * FROM sys_user WHERE user_name = #{userName}")
SysUser selectUserByLoginName(String userName);

2. 动态SQL的安全使用

MyBatis提供了强大的动态SQL功能,但需要正确使用以避免安全风险:

<!-- 安全的动态SQL示例 -->
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
    SELECT * FROM sys_user
    <where>
        <if test="userName != null and userName != ''">
            AND user_name like concat('%', #{userName}, '%')
        </if>
        <if test="status != null and status != ''">
            AND status = #{status}
        </if>
    </where>
</select>

RuoYi框架的SQL注入防护实践

1. SQL工具类的安全过滤

RuoYi在SqlUtil类中实现了严格的SQL注入检测机制:

public class SqlUtil {
    // 定义SQL关键字黑名单
    public static String SQL_REGEX = "\u000B|and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()";
    
    // SQL注入检测方法
    public static void filterKeyword(String value) {
        if (StringUtils.isEmpty(value)) {
            return;
        }
        String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
        for (String sqlKeyword : sqlKeywords) {
            if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) {
                throw new UtilException("参数存在SQL注入风险");
            }
        }
    }
}

2. Order By子句的安全处理

对于动态排序场景,RuoYi实现了严格的安全校验:

public static String escapeOrderBySql(String value) {
    if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) {
        throw new UtilException("参数不符合规范,不能进行查询");
    }
    if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH) {
        throw new UtilException("参数已超过最大限制,不能进行查询");
    }
    return value;
}

// 验证排序字段格式
public static boolean isValidOrderBySql(String value) {
    return value.matches("[a-zA-Z0-9_\\ \\,\\.]+");
}

常见SQL注入场景与防护方案

1. 用户登录场景

mermaid

2. 数据查询场景

// 不安全的写法(存在注入风险)
@Select("SELECT * FROM sys_user WHERE user_name = '${userName}'")
SysUser selectUserUnsafe(String userName);

// 安全的写法(推荐使用)
@Select("SELECT * FROM sys_user WHERE user_name = #{userName}")
SysUser selectUserSafe(String userName);

3. 动态表名和列名场景

对于必须使用动态表名或列名的场景,RuoYi建议:

// 使用白名单机制验证表名
private static final Set<String> ALLOWED_TABLES = 
    Set.of("sys_user", "sys_role", "sys_menu");

public void validateTableName(String tableName) {
    if (!ALLOWED_TABLES.contains(tableName)) {
        throw new UtilException("非法的表名");
    }
}

MyBatis配置最佳实践

1. MyBatis配置类安全设置

@Configuration
public class MyBatisConfig {
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        // 设置类型别名包
        sessionFactory.setTypeAliasesPackage("com.ruoyi.**.domain");
        // 设置mapper文件位置
        sessionFactory.setMapperLocations(resolveMapperLocations(
            StringUtils.split(env.getProperty("mybatis.mapperLocations"), ",")));
        return sessionFactory.getObject();
    }
}

2. 日志监控配置

启用MyBatis的SQL日志监控,便于发现潜在的安全问题:

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

安全开发规范检查表

检查项安全要求风险等级
参数化查询必须使用#{}高危
动态SQL避免直接拼接中危
Order By使用SqlUtil校验中危
Like查询使用concat函数低危
表名/列名白名单验证高危

实战:代码生成器的安全防护

RuoYi的代码生成器在处理自定义SQL时也实现了安全防护:

@RestController
@RequestMapping("/tool/gen")
public class GenController {
    
    @PostMapping("/importTable")
    public AjaxResult importTable(String tables, String sql) {
        // SQL注入检测
        SqlUtil.filterKeyword(sql);
        // 执行安全的数据库操作
        return success(genTableService.importGenTable(tables));
    }
}

总结与建议

RuoYi框架通过多层次的防护策略有效防范SQL注入攻击:

  1. 核心防护:MyBatis参数化查询机制
  2. 补充防护:SqlUtil工具类的关键字过滤
  3. 边界防护:Order By等特殊场景的安全校验
  4. 监控防护:SQL执行日志监控

开发建议

  • 始终坚持使用#{}而不是${}
  • 对用户输入进行严格的验证和过滤
  • 定期进行安全代码审查
  • 使用专业的SQL注入检测工具

通过遵循这些最佳实践,可以显著提升RuoYi应用的安全性,有效防范SQL注入攻击,保障企业数据安全。


安全提示:定期更新框架版本,关注安全漏洞公告,及时修补已知的安全问题。

【免费下载链接】RuoYi 🎉 基于SpringBoot的权限管理系统 易读易懂、界面简洁美观。 核心技术采用Spring、MyBatis、Shiro没有任何其它重度依赖。直接运行即可用 【免费下载链接】RuoYi 项目地址: https://gitcode.com/yangzongzhuan/RuoYi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值