一、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");
}
安全缺陷:
- 除
/ws/sso/login外,其他路径均进行Referer检查 - Referer头可被伪造:
Referer: http://目标域名/ - 攻击者可轻易绕过域名验证
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"};
// ...
}
绕过条件:
- 不包含
ext/trusteeSet路径 - 不包含
ext/flow路径,或对ext/flow仅使用GET请求 - 绝大多数业务接口均可满足这些条件
四、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 完整攻击路径
- 绕过白名单:使用路径跳转技术
- 伪造Referer:设置合法的Referer头
- 避免触发isForbid:选择普通业务接口
- 绕过Ajax验证:不设置x-requested-with头
5.2 风险影响评估
- 未授权访问:可访问任意未在白名单中的功能
- 数据泄露:获取敏感业务数据
- 权限提升:通过未授权接口执行高权限操作
- 业务逻辑绕过:绕过正常业务流程控制
六、修复建议与安全实践
6.1 立即修复措施
- 路径验证强化:
java
scss
// 使用标准化路径进行比较
String normalizedPath = Paths.get(url).normalize().toString();
- Referer验证增强:
java
csharp
// 验证Referer的完整性和来源
if (referer != null && !isValidReferer(referer, serverName)) {
// 拒绝访问并记录审计日志
}
- 移除Ajax特例逻辑:
java
ini
// 统一验证逻辑,不区分Ajax和普通请求
String lang = CookieUtil.getCookie(request, "lang");
if (StringUtils.isBlank(lang)) {
handleSessionTimeout(response);
return;
}