探究SpringWeb对于请求的处理过程
字数 2113 2025-08-20 18:16:58

Spring Web 请求处理过程深度解析

1. 探究目的

本文旨在深入分析 Spring Web 对 HTTP 请求的处理过程,特别是路径归一化机制如何影响安全防护,导致未授权访问漏洞的产生。通过理解 Spring 内部的路由分发机制,可以更好地防范和识别潜在的安全风险。

2. DispatcherServlet 核心作用

DispatcherServlet 是 Spring MVC 的核心组件,实现了前端控制器设计模式,负责接收 HTTP 请求并分发给相应的 Controller 进行处理。其主要功能包括:

  1. 前端控制器模式:作为所有请求的集中入口点,处理公共逻辑
  2. 请求分发:通过 HandlerMapping 组件根据 URL 找到对应的 Controller
  3. 处理器适配:通过 HandlerAdapter 调用处理器方法并包装返回值
  4. 视图解析:通过 ViewResolver 将 ModelAndView 解析为实际视图

3. Spring 请求处理顺序

关键处理流程:

客户端请求 → 过滤器链(FilterChain) → DispatcherServlet → Controller

安全问题的根源在于:过滤器对 URL 的处理与 Spring 最终路由分发时的处理不一致,导致鉴权被绕过。

4. Spring Web 请求处理详细过程

4.1 请求入口

  1. 请求首先经过 FilterChain 中的所有过滤器
  2. 最后调用 DispatcherServlet 的 service 方法
  3. 调用链:DispatcherServlet.service()FrameworkServlet.service()HttpServlet.service()

4.2 核心分发方法 doDispatch

FrameworkServlet.doGet() 方法后,最终调用 DispatcherServlet.doDispatch(),其中关键步骤:

  1. 处理 content-type 为 multipart 的请求
  2. 通过 getHandler(processedRequest) 获取已注册的 HandlerMapping
  3. RequestMappingHandlerMapping 是最常用的 HandlerMapping 实现

4.3 URL 路径处理关键方法

路径处理的核心方法调用链:

getHandlerInternal() → getLookupPathForRequest() → getRequestUri() → decodeAndCleanUriString()

decodeAndCleanUriString() 包含三个关键处理函数:

  1. removeSemicolonContentInternal()

    • 移除所有分号
    • 移除分号后直到下一个斜杠"/"之间的所有字符
    • 这是许多路径归一化问题的根源(如 Shiro 2020-1937)
  2. decodeRequestString()

    • 对 URL 进行 URL 解码
    • 可能导致过滤器未处理编码 URL 而 Spring 解码后绕过鉴权
    • 注意:Nginx 也会对 URL 进行一层解码
  3. getSanitizedPath()

    • 将双斜杠"//"替换为单斜杠"/"

4.4 路径匹配机制

  1. alwaysUseFullPath 属性

    • Spring Boot 2.3.0 RELEASE 之前默认为 false
    • 可以解析 /api/a/../xxxx/api/xxxx
    • 2.3.0 之后默认为 true,不再解析路径中的"../"
  2. 后缀匹配模式

    • useSuffixPatternMatch 为 true 且 spring.mvc.pathmatch.use-suffix-pattern 也为 true 时
    • Spring 1.x 和 Web 4.x 可以解析 /path/path.js 这类带有后缀的请求
    • 可能导致过滤器误判为静态资源请求而绕过鉴权

5. 常见漏洞点总结

  1. 分号处理问题

    • removeSemicolonContentInternal 移除分号及后续字符
    • 示例:/api/xxxxxx;js 被过滤器认为是 JS 文件,但 Spring 分发到 /api/xxxxxx
  2. URL 解码问题

    • decodeRequestString 对 URL 解码
    • 过滤器未处理编码 URL 而 Spring 解码后绕过鉴权
  3. 路径遍历问题

    • Spring Boot <2.3.0 时 alwaysUseFullPath=false
    • 可解析 ../..;/ 导致鉴权绕过
  4. 后缀匹配问题

    • Spring Boot 1.x 支持 /path/path.js 形式
    • 可能被误判为静态资源请求

6. 防御建议

  1. 在过滤器中采用与 Spring 一致的 URL 处理逻辑
  2. 升级到 Spring Boot 2.3.0+ 版本
  3. 禁用后缀模式匹配:spring.mvc.pathmatch.use-suffix-pattern=false
  4. 对静态资源的放行规则要严格,避免使用简单的字符串匹配

7. 参考资源

  1. Spring Framework 官方源码
  2. Butian 技术分享

通过深入理解 Spring Web 的请求处理机制,可以更好地设计和实现安全可靠的 Web 应用程序,有效防范未授权访问等安全风险。

Spring Web 请求处理过程深度解析 1. 探究目的 本文旨在深入分析 Spring Web 对 HTTP 请求的处理过程,特别是路径归一化机制如何影响安全防护,导致未授权访问漏洞的产生。通过理解 Spring 内部的路由分发机制,可以更好地防范和识别潜在的安全风险。 2. DispatcherServlet 核心作用 DispatcherServlet 是 Spring MVC 的核心组件,实现了前端控制器设计模式,负责接收 HTTP 请求并分发给相应的 Controller 进行处理。其主要功能包括: 前端控制器模式 :作为所有请求的集中入口点,处理公共逻辑 请求分发 :通过 HandlerMapping 组件根据 URL 找到对应的 Controller 处理器适配 :通过 HandlerAdapter 调用处理器方法并包装返回值 视图解析 :通过 ViewResolver 将 ModelAndView 解析为实际视图 3. Spring 请求处理顺序 关键处理流程: 安全问题的根源在于: 过滤器对 URL 的处理与 Spring 最终路由分发时的处理不一致 ,导致鉴权被绕过。 4. Spring Web 请求处理详细过程 4.1 请求入口 请求首先经过 FilterChain 中的所有过滤器 最后调用 DispatcherServlet 的 service 方法 调用链: DispatcherServlet.service() → FrameworkServlet.service() → HttpServlet.service() 4.2 核心分发方法 doDispatch 在 FrameworkServlet.doGet() 方法后,最终调用 DispatcherServlet.doDispatch() ,其中关键步骤: 处理 content-type 为 multipart 的请求 通过 getHandler(processedRequest) 获取已注册的 HandlerMapping RequestMappingHandlerMapping 是最常用的 HandlerMapping 实现 4.3 URL 路径处理关键方法 路径处理的核心方法调用链: decodeAndCleanUriString() 包含三个关键处理函数: removeSemicolonContentInternal() 移除所有分号 移除分号后直到下一个斜杠"/"之间的所有字符 这是许多路径归一化问题的根源(如 Shiro 2020-1937) decodeRequestString() 对 URL 进行 URL 解码 可能导致过滤器未处理编码 URL 而 Spring 解码后绕过鉴权 注意:Nginx 也会对 URL 进行一层解码 getSanitizedPath() 将双斜杠"//"替换为单斜杠"/" 4.4 路径匹配机制 alwaysUseFullPath 属性 Spring Boot 2.3.0 RELEASE 之前默认为 false 可以解析 /api/a/../xxxx 为 /api/xxxx 2.3.0 之后默认为 true,不再解析路径中的"../" 后缀匹配模式 useSuffixPatternMatch 为 true 且 spring.mvc.pathmatch.use-suffix-pattern 也为 true 时 Spring 1.x 和 Web 4.x 可以解析 /path/path.js 这类带有后缀的请求 可能导致过滤器误判为静态资源请求而绕过鉴权 5. 常见漏洞点总结 分号处理问题 removeSemicolonContentInternal 移除分号及后续字符 示例: /api/xxxxxx;js 被过滤器认为是 JS 文件,但 Spring 分发到 /api/xxxxxx URL 解码问题 decodeRequestString 对 URL 解码 过滤器未处理编码 URL 而 Spring 解码后绕过鉴权 路径遍历问题 Spring Boot <2.3.0 时 alwaysUseFullPath=false 可解析 ../ 和 ..;/ 导致鉴权绕过 后缀匹配问题 Spring Boot 1.x 支持 /path/path.js 形式 可能被误判为静态资源请求 6. 防御建议 在过滤器中采用与 Spring 一致的 URL 处理逻辑 升级到 Spring Boot 2.3.0+ 版本 禁用后缀模式匹配: spring.mvc.pathmatch.use-suffix-pattern=false 对静态资源的放行规则要严格,避免使用简单的字符串匹配 7. 参考资源 Spring Framework 官方源码 Butian 技术分享 通过深入理解 Spring Web 的请求处理机制,可以更好地设计和实现安全可靠的 Web 应用程序,有效防范未授权访问等安全风险。