探究SpringWeb对于请求的处理过程

探究目的

在路径归一化被提出后,越来越多的未授权漏洞被爆出,而这些未授权多半跟spring自身对路由分发的处理机制有关。今天就来探究一下到底spring处理了什么导致了才导致鉴权被绕过这样严重的问题。

DispatcherServlet介绍

首先在分析spring对请求处理之前之前,首先需要了解DispatcherServlet,它是Spring MVC的核心,负责接收HTTP请求,并根据请求信息分发到相应的Controller进行处理。DispatcherServlet重要特性如下:

  • 前端控制器模式:在Spring MVC框架中,DispatcherServlet实现了前端控制器设计模式。这个模式的主要思想是提供一个中心点,所有的请求将先到达这个中心点,然后由它进行分发。这样可以帮助我们将请求处理流程中的公共逻辑集中处理,从而提高了代码的可维护性。

  • 请求分发:当DispatcherServlet接收到一个HTTP请求后,它会把请求分发给相应的处理器。这个分发的过程主要依赖HandlerMapping组件。HandlerMapping根据请求的URL找到对应的Controller。

  • 处理器适配:找到了正确的处理器之后,DispatcherServlet需要调用这个处理器的方法来处理请求。这个过程由HandlerAdapter负责。HandlerAdapter会调用处理器的适当方法,并将返回值包装成ModelAndView对象。

  • 视图解析:DispatcherServlet还负责将处理器返回的ModelAndView对象解析为实际的视图。这个过程由ViewResolver完成。视图解析器根据ModelAndView中的视图名和已配置的视图解析器来选择一个合适的视图。

Spring对于请求的处理顺序

在具体了解DispatcherServlet如何工作之前需要先了解java项目中各个组件对于url的处理顺序。

图片

看懂该图后,可以清晰地知道大多的路径归一化问题是因为鉴权的过滤器或者拦截器对于url的处理与spring最后对路由分发时的处理不一致,导致鉴权失败,从而可以未授权访问系统。下面就来看看springweb对url究竟是如何解析的

SpringWeb对于请求的处理过程

以springboot2.2x为例自己搭建一个springboot环境,创建好controller后在controller内部打断点。

在调用链中可以清晰地看到,spring对于url的分发确实是在filter之后,接下来

图片

从调用链可以看出在过完Filterchain链上所有的Filter后最后调用了DispatcherServlet的servlet方法。

这里牵扯到一个java的机制,(不想深入了解java的可以略过这段)首先servlet在ApplicationFilterChain.java的225行被反射赋值为DispatcherServlet对象。所以231行调用的是DispatcherServlet的service方法且传入的参数是ServletRequest,ServletResponse类型。但是在DispatcherServlet中并没有service方法,在DispatcherServlet的父类FrameworkServlet中也没有重写接收ServletRequest和ServletResponse的对象service方法,所以调用链到了上一级父类Httpservlet这个抽象类的service方法。Httpservlet中的service方法又调用了接收HttpServletRequest对象的service方法,该方法又被FrameworkServlet重写。故最后调用了FrameworkServlet中的service。完全符合上面的调用链顺序。这里比较绕,大家可以自己跟一下就明白了。网上有很多对于这里的介绍都是错误的,学安全嘛还是要刨根问底一下。源码如下

图片

图片

图片

接着可以看到FrameworkServlet的service方法中super调用了Httpservlet的service方法,值得注意的是在该方法中调用的doGet方法并不是Httpservlet的doGet方法,而是FrameworkServlet的doGet方法。

图片

图片

后面一直跟着调用链走,一直跟进到doDispatch方法。

在该方法中做了很多比较关键的处理。

首先处理了content-type为multipart的请求,后根据mappedHandler = getHandler(processedRequest);这行代码获取了已注册的handlerMappings。

图片

HandlerMapping是一个接口,负责将客户端的HTTP请求映射到对应的Controller。具体来说,它决定哪个Controller应该处理一个给定的请求。其中RequestMappingHandlerMapping用的最多,它支持@RequestMapping注解,并且通常与@Controller注解一起使用。

图片

所以具体处理的逻辑也就在getHandler方法中

图片

这段代码是从已注册的handlerMappings中获取一个HandlerExecutionChain对象,这个对象是对请求要执行的处理器以及其所有相关的拦截器的封装。跟进循环中的getHandler

图片

getHandlerInternal方法是将HTTP请求找到处理这个请求的Handler,然后将其包装到HandlerExecutionChain对象中,以便后续的处理流程。

到了这一步可以确定了,springweb对url的匹配是在getHandlerInternal之中,跟进getHandlerInternal看看其具体实现。

图片

看过路径归一化的师傅们应该到这里就很熟悉了,这个版本的函数叫getLookupPathForRequest,新版本叫initLookupPath。而这行代码也就是为了获得请求路径(通俗说就是我们请求的url)。看看他是怎么处理的

图片

很明显获取url的是 getRequestUri(request)

图片

跟入

图片

decodeAndCleanUriString这个函数可以说是大部分路径归一化问题的罪魁祸首,包括shiro 2020-1937也是因此而起。这三个函数我们挨个看看他到底干了什么

图片

removeSemicolonContentInternal主要做了两件事

1、移除所有的分号

2、移除分号后面直到下一个斜杠”/”之间的所有字符

图片

decodeRequestString函数是对url进行url解码,在这里也要强调一下,经常会看到有师傅用url编码进行鉴权绕过的情况也是由于此处的原因,在过滤器中其实并没有对编码过url进行处理,而到了spring分发路由的时候,却对他进行了解码从而绕过了认证。

顺便提一句,实战过程中可能会碰到Nginx的情况,Nginx也会对url进行一层解码。

图片

图片

getSanitizedPath把双/替换成单/

在此之中removeSemicolonContentInternal问题最大,由于前文处理的模型可以看到url先经过过滤器,如果过滤器中逻辑稍有不当,便有可能存在绕过鉴权的情况。

举个简单的例子

String requestUri =  request.getRequestURI();
If(requestUri.endsWith(“js”)){filterChain.doFilter(servletRequest, servletResponse);
}else{
return ;
}

这是一个常见的对静态文件不进行鉴权的过滤器,然而此时则可以通过/api/xxxxxx;js对该鉴权进行绕过。因为filter处理url时if是通过了if的逻辑,而到了spring的doDispatch中则由刚刚所述的处理,将其分发到了/api/xxxxxx正确对应的接口。

由此产生了很多鉴权问题,在filter之中对url处理稍有不慎变会导致该问题的产生。

再回到springweb对请求的处理,除了刚刚介绍的三个函数对请求的处理之外,还有个地方需要注意,在getLookupPathForRequest之中可以看到this.alwayUseFullPath。这个地方也是一个出现漏洞的点,在springboot2.3.0RELEASE之前spring是可以解析/api/a/../xxxx为/api/xxxx的,是因为this.alwayUseFullPath默认为false,而在springboot2.3.0RELEASE之后,this.alwayUseFullPath默认为true。将无法再解析/api/a/../xxxx,会直接认为该url是个路径,去匹配相应的controller。

图片

有始有终,刚刚只是解析获得了lookuppath也就是请求中的路径,之后再通过前文提到过的getHandlerInternal函数的lookupHandlerMethod对spring获取的url与controller中的url进行匹配。

放几张跟踪的图

图片

图片

图片

图片

图片

跟踪到最后还有个要注意的点,是关于后缀的匹配模式

图片

如果useSuffixPatternMatch为true,且spring配置文件中spring.mvc.pathmatch.use-suffix-pattern的值也为true(我的环境是springweb5.2图中为false)

图片

环境版本高,但是想实验的师傅可以自己配置一下

图片

Spring这时能解析/path/path.js

图片

在1.x版本的springboot和4.x版本的springweb中存在该情况。

该情况也会绕过很多鉴权过滤器,使过滤器误以为用户请求的是静态资源。

总结

常出现漏洞的点

1、removeSemicolonContentInternal函数对分号进行了相关处理导致绕过过滤器鉴权

2、decodeRequestString对url进行解码,此处也可能存在问题

3、在springboot2.3.0RELEASE之前alwayUseFullPath默认值为false,所以可能会导致"../","..;/"绕过鉴权的情况

4、springboot 1.x版本可以解析/path/path.js这类带有后缀的请求,可能造成鉴权绕过

参考链接

https://github.com/spring-projects/spring-framework/

https://forum.butian.net/share/2214

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/126495.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

43、Flink之Hive 读写及详细验证示例

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

React 开发一个移动端项目(1)

技术栈: 项目搭建:React 官方脚手架 create-react-appreact hooks状态管理:redux 、 redux-thunkUI 组件库:antd-mobileajax请求库:axios路由:react-router-dom 以及 historyCSS 预编译器:sass…

计算机竞赛 基于深度学习的视频多目标跟踪实现

文章目录 1 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的视频多目标跟踪实现 …

机器学习笔记之最优化理论与方法(四) 凸函数:定义与基本性质

机器学习笔记之最优化理论与方法——再回首:凸函数定义与基本性质 引言凸函数的定义严格凸函数凸函数的推论:凹函数 常见凸函数凸函数的基本性质几种保持函数凸性的运算凸集与凸函数之间的关联关系 引言 本节将介绍凸函数定义及其基本性质。 本文是关于…

【Unity-Cinemachine相机】相机跟随之Transposer属性

相机跟随和瞄准行为 Transposer:虚拟相机将在某个固定的偏移或距离上跟随目标移动 上面的偏移量就是Follow Offset Binding Mode决定Follow Offset是目标本地坐标系下的身后十米还是世界坐标系下的身后十米 Lock To Target On Assign:锁定自己和目标本地…

第64步 深度学习图像识别:多分类建模误判病例分析(Pytorch)

基于WIN10的64位系统演示 一、写在前面 上期我们基于TensorFlow环境介绍了多分类建模的误判病例分析。 本期以健康组、肺结核组、COVID-19组、细菌性(病毒性)肺炎组为数据集,基于Pytorch环境,构建SqueezeNet多分类模型&#xf…

【漏洞复现】EnjoySCM存在文件上传漏洞

漏洞描述 EnjoySCM是一款适应于零售企业的供应链管理软件,主要为零售企业的供应商提供服务。EnjoySCM的目的是通过信息技术,实现供应商和零售企业的快速、高效、准确的信息沟通、管理信息交流。。 该系统存在任意文件上传漏洞,攻击者通过漏洞可以获取服务器的敏感信息。 …

【监控系统】Promethus整合Alertmanager监控告警邮件通知

【监控系统】Promethus整合Alertmanager监控告警邮件通知 Alertmanager是一种开源软件,用于管理和报警监视警报。它与Prometheus紧密集成,后者是一种流行的开源监视和警报系统。Alertmanager从多个源接收警报和通知,并根据一组配置规则来决定…

【Python】环境的搭建

前言 要想能够进行 Python 开发, 就需要搭建好 Python 的环境. 需要安装的环境主要是两个部分: 运行环境: Python开发环境: PyCharm 一、安装 Python 1.找到官方网站 官网:Welcome to Python.org 2.找到下载页面 点击download中的Windows 3.选择稳定版中的Win…

2023年MySQL实战核心技术第一篇

目录 四 . 基础架构:一条SQl查询语句是如何执行的? 4.1 MySQL逻辑架构图: 4.2 MySQL的Server层和存储引擎层 4.2.1 连接器 4.2.1.1 解释 4.2.1.2 MySQL 异常重启 解决方案: 4.2.1.2.1. 定期断开长连接: 4.2.1.2.2. 初始…

滑动谜题 -- BFS

滑动谜题 输入:board [[4,1,2],[5,0,3]] 输出:5 解释: 最少完成谜板的最少移动次数是 5 , 一种移动路径: 尚未移动: [[4,1,2],[5,0,3]] 移动 1 次: [[4,1,2],[0,5,3]] 移动 2 次: [[0,1,2],[4,5,3]] 移动 3 次: [[1,0,2],[4,5,3]…

计算机网络的故事——了解Web及网络基础

了解Web及网络基础 文章目录 了解Web及网络基础一、使用 HTTP 协议访问 Web二、HTTP 的诞生三、网络基础 TCP/IP四、与 HTTP 关系密切的协议 : IP、TCP 和 DNS 一、使用 HTTP 协议访问 Web 根据Web浏览器指定的URL,从对应的服务器中获取文件资源,从而显…

Java发送(QQ)邮箱、验证码发送

前言 使用Java应用程序发送 E-mail 十分简单,但是首先需要在项目中导入 JavaMail API 和Java Activation Framework (JAF) 的jar包。 菜鸟教程提供的下载链接: JavaMail mail.jar 1.4.5JAF(版本 1.1.1) activation.jar 1、准备…

Mojo-SDK详细安装教程

Mojo-SDK安装 运行环境:windows11wsl2(ubuntu1804) 截至20230909,windows,mac系统暂时不支持 step1: Install VS Code, the WSL extension, and the Mojo extension. step2: Install Ubuntu 22.04 for WSL and open it. step…

openpnp - 底部相机高级矫正后,底部相机看不清吸嘴的解决方法

文章目录 openpnp - 底部相机高级矫正后,底部相机看不清吸嘴的解决方法概述解决思路备注补充 - 新问题 - N1吸嘴到底部相机十字中心的位置差了很多END openpnp - 底部相机高级矫正后,底部相机看不清吸嘴的解决方法 概述 自从用openpnp后, 无论版本(dev/test), 都发现一个大概…

C++多态案例-设计计算器类

1.前置知识点 多态是面向对象的三大特性之一 多态分为两类 静态多态:函数重载和运算符重载都属于静态多态,复用函数名动态多态:派生类和虚函数实现运行时多态 静态多态和动态多态的区别 静态多态的函数地址早绑定-----编译阶段确定函数地…

【JVM】垃圾收集算法

文章目录 分代收集理论标记-清除算法标记-复制算法标记-整理算法 分代收集理论 当前商业虚拟机的垃圾收集器,大多数都遵循了“分代收集”(Generational Collection)[1]的理论进 行设计,分代收集名为理论,实质是一套符…

学会用命令行创建uni-app项目并用vscode开放项目

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 创建 uni-app 项目 命令行创建 uni-app 项目 编译和运行 uni-app 项目: 用 VS Code 开发 uni…

pytest笔记2: fixture

1. fixture 通常是对测试方法和测试函数,测试类整个测试文件进行初始化或是还原测试环境 # 功能函数 def multiply(a, b):return a * b # ------------ fixture---------------def setup_module(module):print("setup_module 在当前文件中所有测试用例之前&q…

项目(智慧教室)第三部分,人机交互在stm32上的实现

一。使用软件 1.stm32cubemx中针对汉字提供的软件 2.对数据进行处理 2.上面点击ok--》这里选择确定 3.这里选择保存即可由字符库,但是需要占用内存太大,需35M,但是stm32只有几百k,所以需要自己删减。 生成中文字符(用…