Shiro 历史漏洞分析
字数 3689 2025-08-26 22:11:22
Apache Shiro 历史漏洞分析与防护指南
1. Shiro 框架概述
Apache Shiro 是一个强大且易用的 Java 安全框架,提供以下核心功能:
- 身份验证(Authentication)
- 授权(Authorization)
- 加密(Cryptography)
- 会话管理(Session Management)
2. Shiro 历史漏洞全解析
2.1 CVE-2010-3863
影响版本:Shiro < 1.1.0 和 JSecurity 0.9.x
漏洞类型:路径标准化缺失导致的权限绕过
漏洞原理:
- Shiro 在权限验证前未对路径进行标准化处理
- 攻击者可利用特殊字符绕过权限校验,如
/./remoting.jsp - 当配置为
/remoting.jsp = authc和/** = anon时,访问/./remoting.jsp会匹配/**规则
修复方案:
- 在 Commit 中增加了路径标准化函数
- 处理
/、//、/./、/../等特殊路径
2.2 CVE-2014-0074 (SHIRO-460)
影响版本:Shiro 1.x < 1.2.3
漏洞类型:LDAP 认证绕过
漏洞原理:
- 当使用 LDAP 服务器并启用非身份验证绑定时
- 攻击者可通过空用户名或空密码绕过身份验证
修复方案:
- 在 Commit 中修复了 LDAP 认证逻辑
2.3 CVE-2016-4437 (SHIRO-550)
影响版本:Shiro 1.x < 1.2.5
漏洞类型:RememberMe 反序列化
漏洞原理:
- 使用硬编码密钥加密 RememberMe cookie
- 攻击者可构造恶意的序列化数据进行反序列化攻击
- 关键类:
AbstractRememberMeManager中的DEFAULT_CIPHER_KEY_BYTES(Base64:kPH+bIxk5D2deZiIxcaaaA==)
利用限制:
- CommonsCollections 链因数组类加载问题可能失败
- 可使用 TemplatesImpl 改造的无数组 CC 链或 CB 链
修复方案:
- 在 1.2.5 版本中改为启动时生成随机密钥
- 允许用户手动配置 cipherKey
2.4 CVE-2016-6802
影响版本:Shiro < 1.3.2
漏洞类型:Context Path 绕过
漏洞原理:
- 类似 CVE-2010-3863,但问题出在 ContextPath 处理上
- 攻击者可构造如
/x/../context/xxx.jsp的路径绕过
修复方案:
- 在
WebUtils.getContextPath中增加路径标准化处理
2.5 CVE-2019-12422 (SHIRO-721)
影响版本:Shiro < 1.4.2
漏洞类型:Padding Oracle Attack
漏洞原理:
- RememberMe 使用 AES-128-CBC 模式加密
- 利用 PKCS5Padding 的特性进行 Padding Oracle 攻击
- 通过判断服务器返回的
rememberMe=deleteMe响应爆破密钥
攻击流程:
- 获取有效的 rememberMe 值
- 生成反序列化 payload
- 使用 Padding Oracle 攻击修改密文
- 发送构造的 rememberMe cookie
修复方案:
- 在 1.4.2 版本中改用 GCM 加密模式
2.6 CVE-2020-1957 (SHIRO-682)
影响版本:Shiro < 1.5.2
漏洞类型:URL 处理差异导致的绕过
漏洞原理:
- Shiro 和 Spring 对 URL 处理存在差异:
- Spring:
/resource/xx与/resource/xx/视为相同 - Shiro:视为不同路径
- Spring:
- 攻击者可利用
/或;绕过:/toJsonPOJO//xx/..;/toJsonPOJO(Spring Boot < 2.3.0.RELEASE)
修复方案:
- 修改 URL 获取逻辑,使用
request.getContextPath()+request.getServletPath()+request.getPathInfo() - 增加对路径后缀
/的支持
2.7 CVE-2020-11989 (SHIRO-782)
影响版本:Shiro < 1.5.3
漏洞类型:双重编码和根路径绕过
漏洞原理:
方式一:双重编码绕过
- 条件:
- Ant 风格配置为
*而非** - Controller 参数类型为 String
- Ant 风格配置为
- Payload:
/toJsonList/a%25%32%66a→ 解码为/toJsonList/a/a- Shiro 进行两次解码,Spring 进行一次解码
方式二:根路径差异化绕过
- 条件:
- Shiro >= 1.5.2 时应用不能部署在根目录
- 无额外权限校验代码
- Payload:
http://localhost:8080/;/shirodemo/alter/test
修复方案:
- 修改 URL 获取逻辑,不单独处理 context-path
- 弃用
WebUtils#getRequestUri,推荐使用getPathWithinApplication()
2.8 CVE-2020-13933
影响版本:Shiro < 1.6.0
漏洞类型:分号编码绕过
漏洞原理:
- 对 CVE-2020-11989 补丁的绕过
- Payload:
/hello/%3ba→ 解码为/hello/;a - Shiro 去除分号后为
/hello,Spring 保留分号
修复方案:
- 在
ShiroFilterFactoryBean中增加/**默认配置 - 添加
InvalidRequestFilter过滤特殊字符
2.9 CVE-2020-17510
影响版本:Shiro < 1.7.0
漏洞类型:点号编码绕过
漏洞原理:
- Payload:
/%2e/%2e%2e/%2e//%2e%2e/
- Shiro 解码后标准化为
/hello,Spring 保留原始路径
修复方案:
- 新增
ShiroUrlPathHelper统一路径处理逻辑 - 需要配置
shiro-spring-boot-web-starter才有效
2.10 CVE-2020-17523
影响版本:Shiro < 1.7.1
漏洞类型:空格编码绕过
漏洞原理:
- Payload:
/hello/%20 AntPathMatcher默认 trim 空格导致匹配错误
修复方案:
- 修改
AntPathMatcher的tokenizeToStringArray方法 - 设置
trimTokens参数为 false
2.11 CVE-2021-41303 (SHIRO-825)
影响版本:Shiro < 1.8.0
漏洞类型:尾部斜线绕过
漏洞原理:
- 配置示例:
map.put("/admin/*", "authc"); map.put("/admin/page", "anon"); - 访问
/admin/page/时:- Shiro 去除斜线后匹配
/admin/page规则 - Spring 仍匹配原始路径
- Shiro 去除斜线后匹配
修复方案:
- 修改
filterChainManager.proxy参数传递逻辑
2.12 CVE-2022-32532
影响版本:Shiro < 1.9.1
漏洞类型:正则表达式绕过
漏洞原理:
- 条件:
- 使用
RegExPatternMatcher - 配置中包含
.的正则表达式
- 使用
- Payload:
/alter/a%0aaa(包含 \n)/alter/a%0daa(包含 \r)
- 正则表达式
.默认不匹配换行符
修复方案:
- 在
Pattern.compile中添加Pattern.DOTALL标志
3. 防护建议
- 及时升级:始终使用最新版 Shiro (当前最新为 ≥1.9.1)
- 安全配置:
- 避免使用
*,优先使用** - 为根路径配置默认权限
- 启用
InvalidRequestFilter
- 避免使用
- 密钥管理:
- 修改默认 RememberMe 密钥
- 使用强随机密钥
- 防御措施:
- 结合 Spring Security 进行多层防护
- 对用户输入进行严格校验
- 实施最小权限原则
4. 漏洞演变趋势分析
Shiro 漏洞主要呈现以下演变趋势:
- 早期:路径标准化缺失 → 硬编码密钥 → 加密模式问题
- 中期:Shiro 与 Spring 的 URL 处理差异
- 近期:正则表达式匹配缺陷
防护重点应从单纯修补转向:
- 统一路径处理标准
- 强化默认安全配置
- 增强加密机制灵活性