CVE-2020-1957源码分析与漏洞复现


漏洞概述

CVE-2020-1957 是 Apache Shiro 框架(1.5.2 之前版本)与 Spring 框架集成时存在的权限绕过漏洞。攻击者通过构造包含特殊字符(如 /;)的 URL 路径,利用 Shiro 与 Spring 对路径解析的差异,绕过权限校验并访问受保护的资源。该漏洞可导致未授权访问敏感接口或数据,CVSS 评分为 7.5(高危)。


技术细节分析

1. 漏洞成因

  • 路径解析差异
    Shiro 的 PathMatchingFilterChainResolver 使用简单的字符串匹配逻辑(基于 AntPathMatcher),而 Spring 的 AntPathMatcher 支持更灵活的路径标准化(如忽略结尾的 / 或解析 ; 后的内容)。例如:

    • Shiro 将 /admin//admin 视为不同路径,而 Spring 可能视为同一路径。
    • Shiro 在处理分号 ; 时会截断后续内容(如 /admin;xxx 解析为 /admin),而 Spring 可能保留完整路径。
  • 配置缺陷
    Shiro 的过滤器链配置若未覆盖所有可能的路径变体(如未配置 /admin/**/admin/),攻击者可构造 /admin//admin;xxx 绕过校验。

2. 源码分析

1
2
3
4
5
6
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
chainDefinition.addPathDefinition("/admin/**", "authc"); // 要求认证
return chainDefinition;
}

问题点

  1. 路径匹配逻辑不严格
    Shiro 的 /admin/** 规则无法匹配 /admin//admin;xxx 等变体路径,导致权限校验失效。
  2. 分号处理缺陷
    Shiro 的 decodeAndCleanUriString 方法会截断分号后的内容(如 /admin;../test 变为 /admin),而 Spring 可能解析为 /test,导致绕过。

攻击示例

  • Payload 1/admin/

    • Shiro 校验路径 /admin/ 不匹配 /admin/**,放行请求。
    • Spring 解析为 /admin,命中 AccountInfoController/admin/ 接口。
  • Payload 2/xxx;/../admin

    • Shiro 截断分号后内容,校验路径 /xxx
    • Spring 解析为 /admin,成功访问受保护资源。

漏洞复现

1.环境搭建

vulhub搭建漏洞环境

upload successful

2.访问8080端口

upload successful

3.访问/admin,出现302

upload successful

4.访问/xxx/..;/admin/

upload successful
绕过权限校验,访问到管理页面


修复方案

  1. 升级 Shiro 版本
    升级至 **Shiro 1.5.3+**,修复了路径标准化和分号处理问题。

  2. 严格路径配置
    在 Shiro 规则中覆盖所有可能变体(如同时配置 /admin/admin/):

    1
    2
    3
    chainDefinition.addPathDefinition("/admin", "authc");
    chainDefinition.addPathDefinition("/admin/", "authc");
    chainDefinition.addPathDefinition("/admin/**", "authc");
  3. 自定义路径标准化过滤器
    强制规范化请求 URI(移除冗余 /;):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class NormalizedPathFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
    String uri = request.getRequestURI();
    String normalizedUri = UriUtils.normalizePath(uri).replaceAll(";.*", "");
    request = new NormalizedHttpServletRequestWrapper(request, normalizedUri);
    chain.doFilter(request, response);
    }
    }

总结

CVE-2020-1957 暴露了 Shiro 与 Spring 集成时路径解析不一致的安全风险。其核心问题在于 Shiro 未对请求路径进行充分标准化,而 Spring 的灵活解析机制被攻击者利用。开发者需结合框架升级、严格配置和自定义过滤器,确保权限校验逻辑覆盖所有可能的路径变体。



CVE-2020-1957源码分析与漏洞复现
https://spinage.top/2025/07/01/CVE-2020-1957源码分析与漏洞复现/
作者
spinage
发布于
2025年7月1日
许可协议