jshERP代码审计(一)
字数 1717 2025-08-23 18:31:34

jshERP代码审计与漏洞分析报告

1. 系统概述

jshERP是一个基于SpringBoot+Mybatis框架开发的企业资源计划系统。系统采用典型的三层架构:

  • Controller层:处理HTTP请求
  • Service层:业务逻辑处理
  • Mapper层:数据库操作

2. SQL时间盲注漏洞

2.1 漏洞位置

  • 文件:MaterialMapperEx.xml
  • 问题:存在未预编译的SQL字段

2.2 漏洞链分析

  1. Mapper层:直接拼接SQL语句
  2. Service层MaterialService.java中的getListWithStockCount方法直接传递参数
    public int getListWithStockCount(List<Long> depotList, List<Long> idList, String position, String materialParam, Integer zeroStock) {
        return materialMapperEx.getListWithStockCount(depList, idList, position, materialParam, zeroStock);
    }
    
  3. Controller层:虽然使用了StringUtil.safeSqlParse()过滤,但过滤不彻底

2.3 过滤机制分析

StringUtil.java中的过滤函数:

public static String safeSqlParse(String originStr) {
    return originStr.replaceAll("(?i)" + regex, "");
}

public final static String regex = "'and | and|and | or | or|or | not | not|not "
    + "| use | use|use | insert | insert|insert | delete | delete|delete | update | update|update "
    + "| select | select|select | count | count|count | group | group|group | union | union|union "
    + "| create | create|create | drop | drop|drop | truncate | truncate|truncate | alter | alter|alter "
    + "| grant | grant|grant | execute | execute|execute | exec | exec|exec | xp_cmdshell | xp_cmdshell|xp_cmdshell "
    + "| call | call|call | declare | declare|declare | source | source|source | sql | sql|sql";

2.4 过滤绕过可能性

  • 未过滤的关键字:sleepcaseifbenchmark
  • 未过滤的符号:括号()、等号=
  • 可构造时间盲注payload如:if(1=1,sleep(5),0)

2.5 漏洞验证

  • 后端MySQL执行日志可见原始SQL语句
  • 可使用SQLMap进行自动化测试

3. 受限的文件上传漏洞

3.1 漏洞位置

  • 文件:SystemConfigController.java
  • 路由:文件上传接口

3.2 上传流程分析

  1. fileUploadType配置默认为1,走systemConfigService.uploadLocal()
  2. bizPath参数可控但未过滤
  3. 默认上传路径:/opt/jshERP/upload
  4. 文件名处理未过滤后缀名

3.3 关键限制因素

  1. 租户ID拼接

    String token = request.getHeader("X-Access-Token");
    Long tenantId = Tools.getTenantIdByToken(token);
    bizPath = bizPath + File.separator + tenantId;
    
    • 从token中提取租户ID并拼接至上传路径
    • 限制了上传目录的可控性
  2. 文件名处理

    public static String getFileName(String fileName) {
        // 过滤路径分隔符
        int unixSep = fileName.lastIndexOf('/');
        int winSep = fileName.lastIndexOf('\\');
        int pos = (winSep > unixSep ? winSep : unixSep);
        if (pos != -1) {
            fileName = fileName.substring(pos + 1);
        }
        // 替换特殊字符
        fileName = fileName.replace("=", "").replace(",", "").replace("&", "");
        return fileName;
    }
    
    • 过滤了路径分隔符,防止目录穿越
    • 未过滤文件后缀名

3.4 利用限制

  • 无法完全控制上传路径
  • 无法通过文件名进行目录穿越
  • 虽然可以上传任意后缀文件,但路径不可控降低了危害

4. Swagger未授权访问

4.1 配置问题

  • 文件:Swagger2Config.java
  • 启用了@EnableSwagger2但未启用@EnableSwaggerBootstrapUI
  • 未在application.properties中配置认证

4.2 白名单设置

  • 文件:LogCostFilter.java
  • 将API接口加入白名单,绕过认证

4.3 风险

  • 暴露系统所有API接口
  • 可能泄露敏感信息
  • 为攻击者提供系统功能概览

5. Fastjson潜在风险

5.1 版本信息

  • Fastjson版本:1.2.83(pom.xml中定义)

5.2 风险分析

  1. 已知问题

    • 1.2.83版本存在反序列化漏洞
    • 公开利用方式有限
  2. 有限利用

    • 可通过java.net.InetSocketAddress触发DNS查询
    • 可用于信息收集和网络探测
  3. 实战应用

    • 可作为干扰手段影响防守方
    • 在特定时机(如交接班时)触发可延长应急响应时间

6. 修复建议

6.1 SQL注入修复

  1. 使用预编译语句替换动态SQL拼接
  2. 完善过滤规则,增加对时间函数和关键字的过滤
  3. 采用ORM框架的绑定参数机制

6.2 文件上传修复

  1. 限制上传文件类型(白名单机制)
  2. 固定上传目录,不依赖用户可控参数
  3. 增加文件内容校验
  4. 设置适当的文件权限

6.3 Swagger访问控制

  1. 生产环境禁用Swagger
  2. 或增加认证机制
  3. 从白名单中移除敏感接口

6.4 Fastjson升级

  1. 升级至最新安全版本
  2. 使用@JSONField(serialize=false)注解保护敏感字段
  3. 配置SerializerFeature禁用危险特性

7. 总结

jshERP系统存在多处安全隐患,从高危的SQL注入到中低危的文件上传和未授权访问问题。建议开发团队:

  1. 优先修复SQL注入和文件上传漏洞
  2. 加强输入验证和输出编码
  3. 实施最小权限原则
  4. 定期进行安全审计和代码审查

通过全面修复这些漏洞,可显著提升系统安全性,降低被攻击风险。

jshERP代码审计与漏洞分析报告 1. 系统概述 jshERP是一个基于SpringBoot+Mybatis框架开发的企业资源计划系统。系统采用典型的三层架构: Controller层:处理HTTP请求 Service层:业务逻辑处理 Mapper层:数据库操作 2. SQL时间盲注漏洞 2.1 漏洞位置 文件: MaterialMapperEx.xml 问题:存在未预编译的SQL字段 2.2 漏洞链分析 Mapper层 :直接拼接SQL语句 Service层 : MaterialService.java 中的 getListWithStockCount 方法直接传递参数 Controller层 :虽然使用了 StringUtil.safeSqlParse() 过滤,但过滤不彻底 2.3 过滤机制分析 StringUtil.java 中的过滤函数: 2.4 过滤绕过可能性 未过滤的关键字: sleep 、 case 、 if 、 benchmark 等 未过滤的符号:括号 () 、等号 = 等 可构造时间盲注payload如: if(1=1,sleep(5),0) 2.5 漏洞验证 后端MySQL执行日志可见原始SQL语句 可使用SQLMap进行自动化测试 3. 受限的文件上传漏洞 3.1 漏洞位置 文件: SystemConfigController.java 路由:文件上传接口 3.2 上传流程分析 fileUploadType 配置默认为1,走 systemConfigService.uploadLocal() bizPath 参数可控但未过滤 默认上传路径: /opt/jshERP/upload 文件名处理未过滤后缀名 3.3 关键限制因素 租户ID拼接 : 从token中提取租户ID并拼接至上传路径 限制了上传目录的可控性 文件名处理 : 过滤了路径分隔符,防止目录穿越 未过滤文件后缀名 3.4 利用限制 无法完全控制上传路径 无法通过文件名进行目录穿越 虽然可以上传任意后缀文件,但路径不可控降低了危害 4. Swagger未授权访问 4.1 配置问题 文件: Swagger2Config.java 启用了 @EnableSwagger2 但未启用 @EnableSwaggerBootstrapUI 未在 application.properties 中配置认证 4.2 白名单设置 文件: LogCostFilter.java 将API接口加入白名单,绕过认证 4.3 风险 暴露系统所有API接口 可能泄露敏感信息 为攻击者提供系统功能概览 5. Fastjson潜在风险 5.1 版本信息 Fastjson版本:1.2.83(pom.xml中定义) 5.2 风险分析 已知问题 : 1.2.83版本存在反序列化漏洞 公开利用方式有限 有限利用 : 可通过 java.net.InetSocketAddress 触发DNS查询 可用于信息收集和网络探测 实战应用 : 可作为干扰手段影响防守方 在特定时机(如交接班时)触发可延长应急响应时间 6. 修复建议 6.1 SQL注入修复 使用预编译语句替换动态SQL拼接 完善过滤规则,增加对时间函数和关键字的过滤 采用ORM框架的绑定参数机制 6.2 文件上传修复 限制上传文件类型(白名单机制) 固定上传目录,不依赖用户可控参数 增加文件内容校验 设置适当的文件权限 6.3 Swagger访问控制 生产环境禁用Swagger 或增加认证机制 从白名单中移除敏感接口 6.4 Fastjson升级 升级至最新安全版本 使用 @JSONField(serialize=false) 注解保护敏感字段 配置 SerializerFeature 禁用危险特性 7. 总结 jshERP系统存在多处安全隐患,从高危的SQL注入到中低危的文件上传和未授权访问问题。建议开发团队: 优先修复SQL注入和文件上传漏洞 加强输入验证和输出编码 实施最小权限原则 定期进行安全审计和代码审查 通过全面修复这些漏洞,可显著提升系统安全性,降低被攻击风险。