JAVA代码审计:鉴权漏洞深度分析

一、SessionFilter的安全迷雾

在进行某系统安全审计时,我们发现了一个关键的SessionFilter过滤器。这个过滤器作为系统的第一道安全防线,本应承担着严格的访问控制职责,但其实现却暗藏玄机,存在多处可绕过的安全隐患。

二、白名单机制:看似安全实则脆弱

2.1 白名单验证逻辑

java

typescript 复制代码
public static boolean isNoNeedValidate(String url, HttpServletRequest request) {
    String[] paths = new String[]{"/login.jsp", "/user/logon.do", "/service/", ...};
    // ... 白名单验证逻辑
}

关键发现:

  • 系统通过request.getContextPath() + path的方式进行路径匹配
  • 只要请求路径以白名单中的任意一项开头,即可绕过鉴权

2.2 路径规范化绕过

绕过手法:

  • 利用../进行路径跳转(低版本Spring框架)
  • 示例:/trwfe/../login.jsp 经过规范化后可能被识别为白名单路径
  • 影响:攻击者可通过精心构造的URL绕过鉴权直接访问受限资源

三、多重检查机制的漏洞分析

3.1 Referer检查可被伪造

java

typescript 复制代码
public boolean isReferer(String url, HttpServletRequest request) {
    String[] paths = new String[]{"/ws/sso/login"};
    // 仅对特定路径禁用Referer检查
    return !url.startsWith(contextPath + "/ws/sso/login");
}

安全缺陷:

  1. 除/ws/sso/login外,其他路径均进行Referer检查
  2. Referer头可被伪造:Referer: http://目标域名/
  3. 攻击者可轻易绕过域名验证

3.2 第三方系统开关的配置依赖

java

kotlin 复制代码
if (Config.THIRD_SYSTEM_SWITCH && "2".equals(Config.THIRD_SYSTEM_TYPE) 
    && this.isForbid(url, request)) {
    response.setStatus(500);
    return;
}

配置风险:

  • 依赖THIRD_SYSTEM_SWITCH和THIRD_SYSTEM_TYPE配置
  • 多线程环境下可能存在配置状态不一致问题
  • 静态配置无法应对动态攻击场景

3.3 isForbid函数的安全盲点

java

typescript 复制代码
private boolean isForbid(String url, HttpServletRequest request) {
    if (url.contains("ext/flow")) {
        // 仅限制非GET方法
        return !"get".equals(method) && !"GET".equals(method);
    }
    // 仅检查特定路径
    String[] paths = new String[]{"ext/trusteeSet"};
    // ...
}

绕过条件:

  1. 不包含ext/trusteeSet路径
  2. 不包含ext/flow路径,或对ext/flow仅使用GET请求
  3. 绝大多数业务接口均可满足这些条件

四、Ajax请求处理的逻辑漏洞

4.1 条件判断缺陷

java

vbscript 复制代码
if (request.getHeader("x-requested-with") != null 
    && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
    // 检查lang cookie
    if (StringUtils.isBlank(lang)) {
        response.setHeader("sessionstatus", "timeout");
        return;
    }
    chain.doFilter(...);
} else {
    // 非Ajax请求直接放行!
    chain.doFilter(...);
}

致命漏洞:

  • 不设置x-requested-with头即可绕过Ajax验证
  • 浏览器默认请求不会自动添加此头
  • 攻击者可轻松构造非Ajax请求绕过会话检查

五、攻击链构造与风险影响

5.1 完整攻击路径

  1. 绕过白名单:使用路径跳转技术
  2. 伪造Referer:设置合法的Referer头
  3. 避免触发isForbid:选择普通业务接口
  4. 绕过Ajax验证:不设置x-requested-with头

5.2 风险影响评估

  • 未授权访问:可访问任意未在白名单中的功能
  • 数据泄露:获取敏感业务数据
  • 权限提升:通过未授权接口执行高权限操作
  • 业务逻辑绕过:绕过正常业务流程控制

六、修复建议与安全实践

6.1 立即修复措施

  1. 路径验证强化:

java

scss 复制代码
// 使用标准化路径进行比较
String normalizedPath = Paths.get(url).normalize().toString();
  1. Referer验证增强:

java

csharp 复制代码
// 验证Referer的完整性和来源
if (referer != null && !isValidReferer(referer, serverName)) {
    // 拒绝访问并记录审计日志
}
  1. 移除Ajax特例逻辑:

java

ini 复制代码
// 统一验证逻辑,不区分Ajax和普通请求
String lang = CookieUtil.getCookie(request, "lang");
if (StringUtils.isBlank(lang)) {
    handleSessionTimeout(response);
    return;
}
相关推荐
小蒜学长35 分钟前
微信小程序-高校自习室管理系统(代码+数据库+LW)
java·spring boot·后端·微信小程序·自习室管理
鸥梨菌Honevid1 小时前
UVM 中 REQ 和 RSP 类型详解:从通信模型到 item_done 与 put_response
java·前端·servlet
瑞克-桑切斯1 小时前
真实企业场景 运维安全与管理
java·网络·github
老板一杯拿铁1 小时前
Java 八股文面试详解:从基础到进阶的全面梳理
java·面试
const_qiu1 小时前
第 2.5 章 2.5.4-2.5.5:JWT 双 Token 与声明式权限守卫
java·人工智能
bug菌1 小时前
一个周末就想把短链服务推到 10 万 QPS,真能靠加 Redis 做到吗?
java·redis·go
撸串-研究生1 小时前
springboot福利院管理系统73979
java·spring boot·后端·福利院管理系统
不得了zz2 小时前
04-Spring AI Alibaba ReactAgent 生产级实践:工具调用、结构化输出、HITL 与上下文管理
java·ai编程·springaialibaba
猿究院_夏燊3 小时前
SpringMVC 到底是怎么干活的?
java·网络·职场和发展
鶴哥只手遮天3 小时前
Spring Framework 7.0.9 深度剖析-05-配置元数据解析:XML、注解与 JavaConfig
java·后端·开源