Apache shiro安全漏洞(CVE-2020-13933)分析
字数 1158 2025-08-20 18:17:47
Apache Shiro安全漏洞(CVE-2020-13933)分析报告
漏洞概述
CVE-2020-13933是Apache Shiro框架中的一个授权绕过漏洞,该漏洞是之前CVE-2020-11989补丁修复不彻底导致的。由于Shiro和Spring框架在处理URL时存在差异,攻击者可以通过构造特殊的HTTP请求绕过授权机制,访问未授权的资源。
影响范围
- Apache Shiro版本 < 1.6.0
- 在Spring框架中仅使用Shiro进行鉴权的系统
漏洞原理
根本原因
漏洞的根本原因在于Shiro和Spring框架对URI处理方式的不同:
-
Shiro处理流程:
- 对URI进行解码
- 去除分号
- 然后进行权限检查
-
Spring处理流程:
- 先检查URI中是否存在分号(但无法识别编码后的分号)
- 然后进行解码
- 最后进行路由匹配
处理差异示例
当传入编码后的URI如/admin/%3bpage时:
-
Shiro处理:
- 解码为
/admin/;page - 去除分号后变为
/admin/page - 由于配置的规则是
/admin/*需要认证,而/admin/page会被正确拦截
- 解码为
-
Spring处理:
- 直接检查原始URI
/admin/%3bpage中是否有分号(未解码,找不到) - 解码后得到
/admin/;page - 最终匹配到
/admin/{name}路由,返回"admin page"
- 直接检查原始URI
漏洞复现
环境配置
@Bean
ShiroFilterFactoryBean shiroFilterFactoryBean(){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager());
bean.setLoginUrl("/login");
bean.setSuccessUrl("/index");
bean.setUnauthorizedUrl("/unauthorizedurl");
Map<String, String> map = new LinkedHashMap<>();
map.put("/doLogin/", "anon"); // 匿名访问
map.put("/admin/*", "authc"); // 需要认证
bean.setFilterChainDefinitionMap(map);
return bean;
}
@GetMapping("/admin/{name}")
public String admin(@PathVariable String name) {
return "admin page";
}
@GetMapping("/login")
public String login() {
return "please login!";
}
攻击方式
构造如下请求即可绕过Shiro的认证检查:
GET /admin/%3bpage HTTP/1.1
Host: vulnerable-app.com
调试分析
-
Shiro处理流程:
- 对URI进行解码并去除分号
- 由于
/admin/没有匹配到具体资源路径,请求会通过过滤器到达Spring
-
Spring处理流程:
- 获取解码前的原始URI
- 在
decodeAndCleanUriString方法中:- 先检查URI中是否存在分号(无法识别编码后的
%3b) - 因此不进入if分支,返回带编码的URI
- 先检查URI中是否存在分号(无法识别编码后的
- 然后进行解码,得到
/admin/;page - 最终匹配到
/admin/{name}路由
漏洞修复
Apache Shiro在1.6.0版本中修复了此漏洞,主要措施是:
- 添加了
InvalidRequestFilter类 - 该过滤器从全局上对以下字符进行过滤:
- 分号
- 反斜杠
- 非ASCII字符
防御建议
- 升级Apache Shiro到1.6.0或更高版本
- 如果无法立即升级,可以自定义过滤器对特殊字符进行过滤
- 统一应用层和框架层的URI处理逻辑
- 实施深度防御策略,不单独依赖Shiro的权限控制
总结
CVE-2020-13933展示了框架间处理逻辑差异可能导致的安全问题。开发人员应当:
- 了解所用框架的安全特性
- 及时应用安全补丁
- 实施多层防御策略
- 定期进行安全审计和渗透测试