CVE-2020-1957 Shiro 权限绕过漏洞在 SpringBoot 高版本下的表现
字数 2034 2025-08-11 08:36:18
Apache Shiro 权限绕过漏洞(CVE-2020-1957)深度分析
漏洞概述
CVE-2020-1957是Apache Shiro框架中的一个权限绕过漏洞,主要由于Shiro与Spring框架对URI路径处理方式存在差异导致。攻击者可以通过构造特殊路径绕过Shiro的权限控制,访问受保护的资源。
漏洞影响版本
- Shiro < 1.5.0
漏洞原理分析
路径处理差异
在Spring框架中:
/drunkbaby/xx与/drunkbaby/xx/会被处理成相同的路径/drunkbaby/xx
而在Shiro中:
/drunkbaby/xx与/drunkbaby/xx/被视为不同的路径
这种解析差异导致攻击者可以通过在路径末尾添加/来绕过Shiro的权限校验。
关键处理流程
-
Shiro处理阶段:
- 处理入口:
org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain() - 关键方法:
pathMatches(),该方法不会将/user/add识别为/user/add/
- 处理入口:
-
Spring处理阶段:
- 处理入口:
org.springframework.web.servlet.DispatcherServlet#doDispatch - 关键方法:
org.springframework.web.servlet.mvc.condition.PatternsRequestCondition#getMatchingPatterns() - Spring会将带
/的路径匹配到正确的handler
- 处理入口:
高版本SpringBoot下的特殊Bypass方式
在高版本SpringBoot中,还存在另一种绕过方式:
- 使用分号构造路径,如
/user;/add
处理流程:
-
Shiro处理阶段:
- 通过
normalize(decodeAndCleanUriString(request, uri))处理URI - 使用
indexOf()截取到;之前的内容,返回/user /user与/user/add不匹配,返回false,导致权限绕过
- 通过
-
Spring处理阶段:
- 通过
removeSemicolonContent()方法处理URI - 最终会正确匹配到
/user/add的handler
- 通过
传统Payload分析
传统Payload形式为/xxx/..;/user/add,但有以下限制:
- 要求SpringBoot版本 < 2.3
- 处理流程:
UrlPathHelper#getLookupPathForRequestdecodeAndCleanUriString()方法依次执行:- 过滤
; - URL解码
- 过滤
//
- 过滤
- 最终返回
/admin/index等路径,实现绕过
环境搭建
参考环境:
https://github.com/Drun1baby/JavaSecurityLearning/tree/main/JavaSecurity/Shiro/shiro682
搭建要点:
- 使用受影响版本的Shiro(<1.5.0)
- 配置SpringBoot环境
- 设置需要权限控制的路径
漏洞复现步骤
- 直接访问受保护路径(如
/authc),应返回302重定向 - 在路径末尾添加
/(如/authc/),成功绕过权限检查 - 或使用分号Payload(如
/user;/add)绕过
调试分析
Shiro调试关键点
- 断点位置:
PathMatchingFilterChainResolver.getChain() - 关注
getPathWithinApplication()方法处理后的URI
Spring调试关键点
- 断点位置:
DispatcherServlet.doDispatch() - 关注
getHandlerInternal()和initLookupPath()方法 - 特别关注
removeSemicolonContent()方法的处理逻辑
漏洞修复
修复方案
- 升级到Shiro 1.5.2及以上版本
- 修复方式变更:
- 不再直接从
request.getRequestUri获取URI - 改为获取request的ContextPath、ServletPath、PathInfo后重新拼接
- 例如
/xxx/..;/user/add会被拼接为//xxx/user/add,无法绕过
- 不再直接从
修复代码分析
修复commit主要修改了URI获取方式,确保路径处理与Spring保持一致。
总结
- 漏洞本质是Shiro与Spring路径解析不一致导致
- 主要利用方式:
- 路径末尾添加
/ - 使用分号构造特殊路径(高版本SpringBoot)
- 传统
/xxx/..;/方式(低版本SpringBoot)
- 路径末尾添加
- 修复关键在于统一路径处理逻辑
参考资源
- 官方修复commit
- 漏洞测试环境:https://github.com/Drun1baby/JavaSecurityLearning
- 相关CVE分析文章