记一次代码审计中发现的几个漏洞
字数 1527 2025-08-24 10:10:13

代码审计实战:从SpringBoot项目中发现的五个漏洞

调试环境配置

  1. 调试Docker中的JAR文件
    • 从Docker Desktop中找到JAR文件位置并保存到本地
    • 在Inspect中找到JAR的路径
    • 新建Java项目,将JAR添加为依赖
    • 解压JAR包到项目根目录,将BOOT-INF/lib目录添加为依赖
    • 将BOOT-INF目录下的class文件添加到依赖关系中
    • 在IDEA配置"Remote JVM Debug"调试环境
    • 修改Docker启动命令,添加调试参数:
      java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar /path/to/jar
      
    • 添加端口映射:-p 127.0.0.1:5005:5005

通用配置审计

  1. 过滤器分析
    • 使用/*匹配所有请求
    • 将ServletRequest转为HttpServletRequest
    • 使用XssAndSqlHttpServletRequestWrapper包装Request对象
    • 通过checkXSSAndSql方法校验请求参数
    • 采用黑名单方式防护XSS和SQL注入

漏洞1:文件上传漏洞

  1. 问题描述

    • 上传功能Controller未对文件类型进行校验
    • Service层的upload方法未校验文件合法性
  2. 验证方法

    • 上传HTML文件执行XSS攻击
  3. 修复建议

    • 实现文件类型白名单校验
    • 校验文件内容与扩展名是否匹配
    • 设置文件上传目录不可执行

漏洞2:不安全的直接对象引用(IDOR)

  1. 问题描述

    • 删除应用的Controller未进行权限校验
    • 直接根据路径变量appTemplateId删除应用
    • 普通用户可删除管理员创建的应用
  2. 验证方法

    • 普通用户调用/delete/{appTemplateId}接口
    • 管理员验证应用已被删除
  3. 修复建议

    • 添加权限校验逻辑
    • 实现资源所有权验证
    • 使用AOP或拦截器统一处理权限

漏洞3:越权漏洞

  1. 问题描述

    • 更新应用信息接口使用AOP注解@DePermissions鉴权
    • 注解配置logical=AND要求两个条件都满足
    • 第一个@DePermission未声明level(默认1)
    • 第二个@DePermission要求level=5
    • access方法中如果参数为空直接返回true
  2. 绕过方法

    • 普通用户(level=1)调用更新接口
    • 不传入pid参数,使对应注解校验为空
    • 绕过level=5的权限校验
  3. 修复建议

    • 严格校验所有必填参数
    • 修改access方法空参数处理逻辑
    • 统一权限校验标准

漏洞4:权限绕过漏洞

  1. 问题描述

    • 查看用户信息接口要求level=3
    • 普通用户level=1无法访问
    • AuthUtils.permissionByType自动添加level=3,值为0的数据集
    • 通过/api/user/userGrid/0可绕过权限检查
  2. 修复建议

    • 移除自动添加的测试数据集
    • 加强权限校验逻辑
    • 实现最小权限原则

漏洞5:SQL注入漏洞

  1. 问题描述

    • MyBatis中使用${sort}进行SQL拼接
    • 虽然过滤器有SQL关键字黑名单
    • 但可使用非常见函数如GTID_SUBSET绕过
  2. 验证方法

    • 找到sort参数可控的Controller
    • 使用黑名单外的SQL函数构造注入
  3. 修复建议

    • 使用#{}预编译方式替代${}
    • 实现sort参数白名单校验
    • 加强SQL注入过滤规则

总结

  1. 审计方法论

    • 先分析通用配置(过滤器、拦截器等)
    • 重点关注用户输入处理
    • 检查权限校验实现
    • 审计SQL语句构建方式
  2. 常见漏洞模式

    • 缺失或不当的输入验证
    • 不完善的权限校验
    • 不安全的直接对象引用
    • SQL语句拼接风险
  3. 防御建议

    • 实施最小权限原则
    • 使用白名单替代黑名单
    • 统一安全处理逻辑
    • 定期进行代码审计
代码审计实战:从SpringBoot项目中发现的五个漏洞 调试环境配置 调试Docker中的JAR文件 : 从Docker Desktop中找到JAR文件位置并保存到本地 在Inspect中找到JAR的路径 新建Java项目,将JAR添加为依赖 解压JAR包到项目根目录,将BOOT-INF/lib目录添加为依赖 将BOOT-INF目录下的class文件添加到依赖关系中 在IDEA配置"Remote JVM Debug"调试环境 修改Docker启动命令,添加调试参数: 添加端口映射: -p 127.0.0.1:5005:5005 通用配置审计 过滤器分析 : 使用 /* 匹配所有请求 将ServletRequest转为HttpServletRequest 使用XssAndSqlHttpServletRequestWrapper包装Request对象 通过checkXSSAndSql方法校验请求参数 采用黑名单方式防护XSS和SQL注入 漏洞1:文件上传漏洞 问题描述 : 上传功能Controller未对文件类型进行校验 Service层的upload方法未校验文件合法性 验证方法 : 上传HTML文件执行XSS攻击 修复建议 : 实现文件类型白名单校验 校验文件内容与扩展名是否匹配 设置文件上传目录不可执行 漏洞2:不安全的直接对象引用(IDOR) 问题描述 : 删除应用的Controller未进行权限校验 直接根据路径变量appTemplateId删除应用 普通用户可删除管理员创建的应用 验证方法 : 普通用户调用 /delete/{appTemplateId} 接口 管理员验证应用已被删除 修复建议 : 添加权限校验逻辑 实现资源所有权验证 使用AOP或拦截器统一处理权限 漏洞3:越权漏洞 问题描述 : 更新应用信息接口使用AOP注解 @DePermissions 鉴权 注解配置 logical=AND 要求两个条件都满足 第一个 @DePermission 未声明level(默认1) 第二个 @DePermission 要求level=5 access方法中如果参数为空直接返回true 绕过方法 : 普通用户(level=1)调用更新接口 不传入pid参数,使对应注解校验为空 绕过level=5的权限校验 修复建议 : 严格校验所有必填参数 修改access方法空参数处理逻辑 统一权限校验标准 漏洞4:权限绕过漏洞 问题描述 : 查看用户信息接口要求level=3 普通用户level=1无法访问 AuthUtils.permissionByType自动添加level=3,值为0的数据集 通过 /api/user/userGrid/0 可绕过权限检查 修复建议 : 移除自动添加的测试数据集 加强权限校验逻辑 实现最小权限原则 漏洞5:SQL注入漏洞 问题描述 : MyBatis中使用 ${sort} 进行SQL拼接 虽然过滤器有SQL关键字黑名单 但可使用非常见函数如GTID_ SUBSET绕过 验证方法 : 找到sort参数可控的Controller 使用黑名单外的SQL函数构造注入 修复建议 : 使用 #{} 预编译方式替代 ${} 实现sort参数白名单校验 加强SQL注入过滤规则 总结 审计方法论 : 先分析通用配置(过滤器、拦截器等) 重点关注用户输入处理 检查权限校验实现 审计SQL语句构建方式 常见漏洞模式 : 缺失或不当的输入验证 不完善的权限校验 不安全的直接对象引用 SQL语句拼接风险 防御建议 : 实施最小权限原则 使用白名单替代黑名单 统一安全处理逻辑 定期进行代码审计