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 漏洞链分析
- Mapper层:直接拼接SQL语句
- 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); } - 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 过滤绕过可能性
- 未过滤的关键字:
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拼接:
String token = request.getHeader("X-Access-Token"); Long tenantId = Tools.getTenantIdByToken(token); bizPath = bizPath + File.separator + tenantId;- 从token中提取租户ID并拼接至上传路径
- 限制了上传目录的可控性
-
文件名处理:
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.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注入和文件上传漏洞
- 加强输入验证和输出编码
- 实施最小权限原则
- 定期进行安全审计和代码审查
通过全面修复这些漏洞,可显著提升系统安全性,降低被攻击风险。