Spring WebMvc.fn路由解析与权限绕过浅析
字数 2638 2025-08-20 18:18:10

Spring WebMvc.fn路由解析与权限绕过分析

0x00 前言

Spring WebMvc.fn是Spring Web MVC的一部分,提供了一种轻量级的函数式编程模型,允许开发者使用函数来定义路由和处理HTTP请求。这种模型是注解编程模型的替代方案。

在WebMvc.fn中:

  • HTTP请求由HandlerFunction处理
  • 这是一个接收ServerRequest并返回ServerResponse的函数
  • 一般通过RouterFunctions.route()方法进行处理

示例代码:

@Configuration
public class PersonHandlerConfiguration {
    @Bean
    public RouterFunction<ServerResponse> person() {
        return route().GET("/person", request -> {
            return ServerResponse.status(HttpStatus.OK).body("Hello World");
        }).build();
    }
}

0x01 WebMvc.fn路由解析过程

核心解析流程

  1. DispatcherServlet处理:Spring MVC接收到请求时,Servlet容器调用DispatcherServletservice方法

  2. 请求方法分发:根据请求方法调用对应的processRequest方法(如GET请求调用doGet方法)

  3. HandlerMapping查找:在doDispatch方法中循环调用HandlerMappinggetHandler方法

    • WebMvc.fn使用RouterFunctionMapping
  4. RouterFunctionMapping处理

    • 检查this.routerFunction是否不为null
    • 使用HttpServletRequest创建ServerRequest对象
    • 使用routerFunction.route(request)路由请求
    • 尝试匹配ServerRequestRouterFunction中定义的路由规则
  5. 路由匹配

    • 调用org.springframework.web.servlet.function.RouterFunctionBuilder#route方法
    • 遍历路由函数routerFunctionsroute方法
    • 找到第一个与当前请求匹配的路由,返回相应的HandlerFunction
  6. 请求规则检查

    • RequestPredicates定义请求规则(请求参数、请求方式等)
    • 调用DefaultRouterFunction#route方法
    • 通过this.predicate.test(request)检查路由函数的Predicate是否匹配
  7. 路径匹配

    • 检查请求方法是否在路由函数的方法集合中
    • 通过PathPatternmatchAndExtract方法进行请求路径匹配

多RouterFunction处理

当容器中有多个RouterFunction类型的bean时:

  • DifferentComposedRouterFunction会逐层包装所有RouterFunction
  • 调用DifferentComposedRouterFunction#route方法
  • 递归调用最终到达配置类中定义的BuiltRouterFunction#route

静态资源解析

RouterFunctions可以通过PathResourceLookupFunction处理静态资源请求,将请求路径映射到文件系统中的资源。

解析流程:

  1. 调用ResourcesRouterFunction#route方法
  2. 实际调用org.springframework.web.servlet.function.PathResourceLookupFunction#apply方法
  3. 检查请求路径是否与定义的路由模式匹配
  4. 提取模式内的路径部分
  5. 对路径进行处理(若包含%则进行URL解码)
  6. 检查路径合法性
  7. 创建Resource对象并检查可读性和位置安全性

路径安全检查

  • 检查是否包含WEB-INFMETA-INF
  • 检查是否是有效的URL(如classpath:
  • 检查是否包含..(路径遍历尝试)
  • 使用StringUtils.cleanPath(path)处理路径

0x02 RouterFunctionMapping权限绕过分析

基本绕过思路

  1. 路径解析特性

    • 使用request.requestPath().pathWithinApplication获取请求路径
    • 移除URL路径中的分号
    • 对URL编码进行解码操作
    • 识别请求path尾部额外的/
  2. 变形路径示例

    • /person
    • /person/
    • /person%2f
    • /person%252f(双重编码)

静态资源访问控制绕过

案例场景:通过RouterFunction定义路由,使用filter对特定路径下特定后缀文件进行权限控制。

示例配置:

@Configuration
public class LogRouter {
    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    
    @Bean
    RouterFunction staticResourceLocator(){
        return RouterFunctions.resources("/log/**", resolver.getResource("file:///usr/local/tomcat/logs/"));
    }
}

绕过分析

  1. URL解码过程

    • 原始请求路径包含%时,会进行一次URL解码
    • ResourceUtils#getFile方法中,通过URI对象的getSchemeSpecificPart方法再做一层解码
    • 实际请求时会对路径解码两次
  2. 安全检查限制

    • #会被替换为URL编码,无法使用file:///path/file.log#png方式绕过后缀匹配
    • 路径中不能包含../等穿越符
  3. 双重编码绕过

    • 通过双重URL编码可以绕过权限控制
    • 示例:读取catalina.out文件
      • 原始路径:/log/catalina.out
      • 双重编码:/log/catalina%252eout

通用鉴权措施绕过

对于使用类似Shiro/Spring Security等通用鉴权措施:

  • 利用不同场景下的解析差异
  • 结合路径变形和编码方式

0x03 安全建议

  1. 使用内置安全机制

    • 使用路由函数生成器上的beforeafterfilter方法
    • 示例:
      return route()
          .GET("/person", request -> {...})
          .before(request -> {
              // 认证逻辑
              return request;
          })
          .build();
      
  2. 路径处理建议

    • 严格校验请求路径
    • 避免依赖单一的安全检查
    • 对资源访问实施多层验证
  3. 静态资源控制

    • 限制文件系统访问范围
    • 实施严格的路径规范化检查
    • 考虑使用白名单机制
  4. 编码处理

    • 统一编码解码处理流程
    • 避免多次解码导致的安全问题
  5. 版本更新

    • 保持Spring框架最新版本
    • 关注安全公告和补丁

总结

Spring WebMvc.fn提供了灵活的路由定义方式,但在路径处理和权限控制方面存在潜在风险。开发者需要充分理解其路由解析机制,特别注意路径变形和编码带来的安全问题,实施多层次的安全防护措施。

Spring WebMvc.fn路由解析与权限绕过分析 0x00 前言 Spring WebMvc.fn是Spring Web MVC的一部分,提供了一种轻量级的函数式编程模型,允许开发者使用函数来定义路由和处理HTTP请求。这种模型是注解编程模型的替代方案。 在WebMvc.fn中: HTTP请求由 HandlerFunction 处理 这是一个接收 ServerRequest 并返回 ServerResponse 的函数 一般通过 RouterFunctions.route() 方法进行处理 示例代码: 0x01 WebMvc.fn路由解析过程 核心解析流程 DispatcherServlet处理 :Spring MVC接收到请求时,Servlet容器调用 DispatcherServlet 的 service 方法 请求方法分发 :根据请求方法调用对应的 processRequest 方法(如GET请求调用 doGet 方法) HandlerMapping查找 :在 doDispatch 方法中循环调用 HandlerMapping 的 getHandler 方法 WebMvc.fn使用 RouterFunctionMapping RouterFunctionMapping处理 : 检查 this.routerFunction 是否不为null 使用 HttpServletRequest 创建 ServerRequest 对象 使用 routerFunction.route(request) 路由请求 尝试匹配 ServerRequest 与 RouterFunction 中定义的路由规则 路由匹配 : 调用 org.springframework.web.servlet.function.RouterFunctionBuilder#route 方法 遍历路由函数 routerFunctions 的 route 方法 找到第一个与当前请求匹配的路由,返回相应的 HandlerFunction 请求规则检查 : RequestPredicates 定义请求规则(请求参数、请求方式等) 调用 DefaultRouterFunction#route 方法 通过 this.predicate.test(request) 检查路由函数的 Predicate 是否匹配 路径匹配 : 检查请求方法是否在路由函数的方法集合中 通过 PathPattern 的 matchAndExtract 方法进行请求路径匹配 多RouterFunction处理 当容器中有多个 RouterFunction 类型的bean时: DifferentComposedRouterFunction 会逐层包装所有 RouterFunction 调用 DifferentComposedRouterFunction#route 方法 递归调用最终到达配置类中定义的 BuiltRouterFunction#route 静态资源解析 RouterFunctions 可以通过 PathResourceLookupFunction 处理静态资源请求,将请求路径映射到文件系统中的资源。 解析流程: 调用 ResourcesRouterFunction#route 方法 实际调用 org.springframework.web.servlet.function.PathResourceLookupFunction#apply 方法 检查请求路径是否与定义的路由模式匹配 提取模式内的路径部分 对路径进行处理(若包含 % 则进行URL解码) 检查路径合法性 创建 Resource 对象并检查可读性和位置安全性 路径安全检查 : 检查是否包含 WEB-INF 或 META-INF 检查是否是有效的URL(如 classpath: ) 检查是否包含 .. (路径遍历尝试) 使用 StringUtils.cleanPath(path) 处理路径 0x02 RouterFunctionMapping权限绕过分析 基本绕过思路 路径解析特性 : 使用 request.requestPath().pathWithinApplication 获取请求路径 移除URL路径中的分号 对URL编码进行解码操作 识别请求path尾部额外的 / 变形路径示例 : /person /person/ /person%2f /person%252f (双重编码) 静态资源访问控制绕过 案例场景:通过 RouterFunction 定义路由,使用 filter 对特定路径下特定后缀文件进行权限控制。 示例配置: 绕过分析 : URL解码过程 : 原始请求路径包含 % 时,会进行一次URL解码 在 ResourceUtils#getFile 方法中,通过URI对象的 getSchemeSpecificPart 方法再做一层解码 实际请求时会对路径解码两次 安全检查限制 : # 会被替换为URL编码,无法使用 file:///path/file.log#png 方式绕过后缀匹配 路径中不能包含 ../ 等穿越符 双重编码绕过 : 通过双重URL编码可以绕过权限控制 示例:读取 catalina.out 文件 原始路径: /log/catalina.out 双重编码: /log/catalina%252eout 通用鉴权措施绕过 对于使用类似Shiro/Spring Security等通用鉴权措施: 利用不同场景下的解析差异 结合路径变形和编码方式 0x03 安全建议 使用内置安全机制 : 使用路由函数生成器上的 before 、 after 或 filter 方法 示例: 路径处理建议 : 严格校验请求路径 避免依赖单一的安全检查 对资源访问实施多层验证 静态资源控制 : 限制文件系统访问范围 实施严格的路径规范化检查 考虑使用白名单机制 编码处理 : 统一编码解码处理流程 避免多次解码导致的安全问题 版本更新 : 保持Spring框架最新版本 关注安全公告和补丁 总结 Spring WebMvc.fn提供了灵活的路由定义方式,但在路径处理和权限控制方面存在潜在风险。开发者需要充分理解其路由解析机制,特别注意路径变形和编码带来的安全问题,实施多层次的安全防护措施。