原因一Tomcat 的路径解析行为核心规范 Servlet 规范 (JSR 369) 定义了如何处理请求 URI。分号 ; 被定义为路径参数Path Parameters 的分隔符。Tomcat 的实现 (org.apache.catalina.connector.Request):当收到请求 GET /kds-sale-api/;/web/correction/getOrganizationList HTTP/1.1 时Tomcat 开始解析 URI。parsePathParameters() 方法:扫描 URI 路径部分查找分号 ;。一旦找到分号它会将 ; 及其之后直到下一个 / 或字符串结束的部分例如 ;/视为路径参数。核心操作 Tomcat 会临时移除这些路径参数部分形成一个 “规范化路径 (Normalized Path)”。这个过程称为 “路径规范化”。示例原始 URI: /;/web/correction/getOrganizationList规范化后路径: /web/correction/getOrganizationList (;/ 被移除)getServletPath() 和 getPathInfo(): 这两个 HttpServletRequest 方法返回的值是基于规范化路径计算的不包含路径参数。request.getServletPath(): 返回匹配 Servlet 映射的部分request.getPathInfo(): 返回 Servlet 路径之后的额外路径信息Spring MVC 的路径映射处理DispatcherServlet 接收到 Tomcat 传递过来的请求。如前所述Tomcat 已经将规范化路径 (/web/correction/getOrganizationList) 设置到 request 的 servletPath 和 pathInfo 中。查找 Handler (Controller 方法):HandlerMapping (如 RequestMappingHandlerMapping) 负责根据请求查找对应的 Controller 方法。它主要使用 request.getServletPath() request.getPathInfo() (即 Tomcat 规范化后的路径 /web/correction/getOrganizationList) 来匹配 RequestMapping 注解中定义的路径。Controller 方法正常执行。结论由于 Tomcat 的规范化Spring MVC 最终处理的是 /web/correction/getOrganizationList。Controller 方法看到的路径是“干净”的与正常访问无异。漏洞的关键在于 Shiro 错误地让这个请求通过了安全检查。原因二Shiro 的路径匹配逻辑(存在漏洞的版本 1.7.1)Shiro 的保护机制Shiro 通过 ShiroFilter (通常映射到 /**) 拦截所有请求。它使用配置的 [urls] 规则和 PathMatchingFilterChainResolver 来决定哪个过滤器链如 authc应用于当前请求。PathMatchingFilterChainResolver 的工作流程:1. 获取请求路径 getPathWithinApplication(request)在存在漏洞的版本 ( 1.7.1) 中Shiro 的默认实现 (WebUtils.getPathWithinApplication) 可能直接使用了 request.getRequestURI() request.getRequestURI() 返回的是原始请求 URI /;/web/correction/getOrganizationList。注意这里仍然包含 ;/2. 路径匹配 (AntPathMatcher):Shiro 使用类似 Ant 风格的路径模式匹配器 (org.apache.shiro.util.AntPathMatcher) 将上一步得到的路径 ( /;/web/correction/getOrganizationList) 与 [urls] 中配置的模式 (如 /**) 进行比较。漏洞点 (CVE-2020-17523):CVE-2020-17523 (关键): 这是一个历史悠久的 Shiro 漏洞在 2020 年底被修复1.7.1 版本修复。在这个漏洞存在时Shiro 在进行路径匹配时没有正确处理分号 ;。AntPathMatcher 的缺陷 (旧版本): 在 1.7.1 之前的版本中AntPathMatcher 没有正确处理分号 ;。匹配失败的原因: 它将包含分号的路径 /;/web/correction/getOrganizationList 视为一个整体字符串。AntPathMatcher 在解析 /;/web/correction/getOrganizationList 时它看到 /; 不符合 ** 对“目录/文件”的预期。; 被当作普通字符但 ** 期望的是 / 分隔的层级结构。结果AntPathMatcher 认为 /;/web/correction/getOrganizationList 不匹配 模式 /**。绕过发生 因为请求路径 (/;/web/correction/getOrganizationList) 没有匹配到任何配置了安全约束 (如 authc) 的 [urls] 模式PathMatchingFilterChainResolver 会返回一个默认的、无安全控制的过滤器链通常是 anon 链。请求被允许通过 Shiro 的安全检查继续向下传递到 Servlet 容器如 Spring MVC DispatcherServlet。解决方案可以自定义一个过滤器在Shiro之前对URI进行处理版本升级Shiro 1.7.1 修复了 CVE-2020-17523核心修改在路径获取和匹配逻辑2.1 改进的路径获取 (WebUtils.getPathWithinApplication):获取路径后显式移除分号及其后的路径参数。这是对 Tomcat 规范化行为的主动模拟。处理请求 /;/web/correction/getOrganizationList移除路径参数: 查找 ;移除 ;/ → 得到 /web/correction/getOrganizationList2.2 改进的 AntPathMatcher :AntPathMatcher 本身也进行了增强确保在处理路径时能正确忽略或处理分号。匹配过程修复:Shiro 现在使用规范化后的路径 (/web/correction/getOrganizationList) 去匹配配置的模式 (/**)。/web/correction/getOrganizationList 显然匹配 /** → 触发 authc 链 → 要求认证 → 安全拦截生效。总结修复的核心是 强制 Shiro 使用与 Tomcat 和最终业务逻辑Spring MVC一致的、移除路径参数后的规范化路径进行安全规则匹配。