Java 代码审计之华夏 ERP CMS v2.3
字数 1371 2025-08-12 11:34:48
华夏ERP CMS v2.3 代码审计与漏洞分析教学文档
一、审计准备
1. 环境分析
- 项目版本:华夏ERP v2.3
- 主要组件:
- Fastjson 1.2.55(存在反序列化漏洞风险)
- MyBatis(需关注SQL注入风险)
- Log4j2(需验证是否存在漏洞)
2. 审计方法论
- 先分析
pom.xml了解项目依赖 - 审查Filter配置和安全机制
- 按漏洞类型进行专项审计
二、Filter安全分析
1. Filter配置
@WebInitParam(name = "ignoredUrl", value = ".css#.js#.jpg#.png#.gif#.ico,/user/login#/user/registerUser#/v2/api-docs")
2. 主要安全问题
-
资源文件过滤不严:
- 仅使用正则匹配,未使用
endsWith()严格判断 - 可绕过:
/1.css/../home.html
- 仅使用正则匹配,未使用
-
URL白名单绕过:
- 使用
startsWith()判断,可通过目录穿越绕过 - 示例:
/login.html/../home.html
- 使用
-
缺失关键过滤:
- 无XSS过滤
- 无SQL注入过滤
三、SQL注入漏洞
1. 漏洞位置
- 文件:
UserMapperEx.xml - 危险语句:
<select id="countsByUser" resultType="java.lang.Long">
SELECT count(id)
FROM jsh_user
WHERE 1=1
<if test="userName != null and userName != ''">
AND userName like '%${userName}%'
</if>
<if test="loginName != null and loginName != ''">
AND loginName like '%${loginName}%'
</if>
</select>
2. 触发方式
- 接口:
/user/list - 参数:
userName或loginName - Payload:
search={"userName":"test' AND (SELECT 1 FROM (SELECT SLEEP(5))a)-- "}
3. 修复方案
- 使用
#{}替换${} - 添加Filter过滤特殊字符:
public static boolean sqlValidate(String str) {
str = str.toLowerCase();
String badStr = "select|update|and|or|delete|insert|truncate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute|table";
String[] badStrs = badStr.split("\\|");
for (String bad : badStrs) {
if (str.indexOf(bad) >= 0) {
return true;
}
}
return false;
}
四、XSS漏洞
1. 存储型XSS
- 位置:多处用户输入点(如备注字段、用户名等)
- 示例:
- 访问:
/index.html#/pages/financial/item_in.html - 在备注字段插入XSS payload
- 访问:
2. 修复方案
private String cleanXSS(String value) {
value = value.replaceAll("<", "<").replaceAll(">", ">");
value = value.replaceAll("\$", "(").replaceAll("\$", ")");
value = value.replaceAll("'", "'");
value = value.replaceAll("eval\$(.*)\$", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value = value.replaceAll("script", "");
return value;
}
五、Fastjson反序列化漏洞
1. 漏洞详情
- Fastjson版本:1.2.55
- 危险方法:
JSON.parseObject() - 触发点:
StringUtil.getInfo()
2. 验证方式
- Payload:
{"@type":"java.net.Inet4Address","val":"dnslog.com"}
3. 修复建议
- 升级Fastjson至最新安全版本
- 关闭AutoType:
ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
六、越权漏洞
1. 密码重置越权
- 接口:
/user/resetPassword - 问题代码:
if ("admin".equals(loginName)) {
// 不允许直接重置管理员密码
} else {
user.setPassword("123456");
}
- 攻击方式:修改
userId参数可重置任意用户密码
2. 用户删除越权
- 接口:
/user/deleteUser - 问题:未校验操作者权限
3. 修复方案
Long userId = userEx.getId();
String loginName = userEx.getLoginName();
if (userId.equals(getIdByLoginName(loginName))) {
// 允许操作
} else {
return;
}
七、目录遍历防御
1. 修复代码
public static String filenameFilter(String str) {
if(str == null) return null;
return str.replaceAll("\\.\\./", "");
}
八、Log4j2漏洞验证
1. 分析结论
- 经测试,当前版本不存在Log4j2漏洞
- 原因:Maven依赖中不包含易受攻击的Log4j-core组件
九、综合修复建议
-
输入过滤:
- 添加统一的XSS和SQL注入Filter
- 对特殊字符进行转义或过滤
-
权限控制:
- 添加细粒度的权限校验
- 关键操作需二次确认
-
组件升级:
- 升级Fastjson至最新安全版本
- 定期检查第三方组件安全性
-
安全编码:
- 使用预编译语句防止SQL注入
- 输出编码防止XSS
- 严格校验用户输入和操作权限
十、审计总结
-
典型漏洞:
- 未授权访问(目录遍历绕过)
- SQL注入(MyBatis不当使用)
- 存储型XSS(输出未编码)
- Fastjson反序列化(版本过低)
- 水平/垂直越权(权限校验缺失)
-
审计技巧:
- 全局搜索危险函数(如
like、parseObject) - 跟踪用户输入传递路径
- 验证Filter的有效性
- 检查权限校验逻辑
- 全局搜索危险函数(如
-
防御思路:
- 最小权限原则
- 防御深度原则
- 不信任任何用户输入
- 安全默认配置