首页 > 其他分享 >浅谈SpringSecurity与CVE-2023-22602

浅谈SpringSecurity与CVE-2023-22602

时间:2023-06-30 11:46:10浏览次数:50  
标签:解析 匹配 浅谈 admin Spring 22602 SpringSecurity PathPattern CVE

一、前言

  前段时间Apache报告了CVE-2023-22602,由于 1.11.0 及之前版本的 Shiro 只兼容 Spring 的ant-style路径匹配模式(pattern matching),且 2.6 及之后版本的 Spring Boot 将 Spring MVC 处理请求的路径匹配模式从AntPathMatcher更改为了PathPatternParser,当 1.11.0 及之前版本的 Apache Shiro 和 2.6 及之后版本的 Spring Boot 使用不同的路径匹配模式时,攻击者访问可绕过 Shiro 的身份验证。

  在Java生态中,还有一个常用的鉴权组件SpringSecurity,其中AntPathRequestMatcher是SpringSecurity中基于Ant风格模式进行匹配的实现类,那么是否也会有类似的问题。查看源码进行简单的分析:

wKg0C2Qq5WqAPPYfAAAktHbm7U683.png

二、相关原理

  按照前面的猜想,SpringSecurity某种条件下使用的是AntPathMatcher进行匹配,而高版本的Spring使用的是PathPatternParser,利用解析的差异在某些条件下可能会存在绕过鉴权的风险。

  AntPathRequestMatcher是SpringSecurity中基于Ant风格模式进行匹配的实现类。一般使用如下:

protected void configure(HttpSecurity httpSecurity) throws Exception{
     httpSecurity.authorizeRequests().antMatchers("/admin/*").authenticated();
}

  查看AntPathRequestMatcher以及PathPattern的具体实现:

  主要的匹配在org.springframework.security.web.util.matcher.AntPathRequestMatcher#matches方法中进行。

  首先判断请求方法是否一致,然后如果pattern是/**的话,说明是全路径匹配返回true。否则获取当前请求的url,然后调用当前matcher的matches方法进行进一步的匹配:

wKg0C2Qq6FSALtkRAAA8yrdNIt8959.png

  首先是当前请求url的获取方法,如果没有配置urlPathHelper的话,则通过请求的ServletPath和PathInfo进行拼接,获取归一化处理后的url,否则调用Spring中的 UrlPathHelper (封装了有很多与URL路径处理有关的方法)的getPathWithinApplication方法(进行了URI解码、移除分号内容并清理斜线等进一步的处理)进行获取:

wKg0C2Qq6IOAQjNtAACDvlWTI0A203.png

  获取完url后,会调用当前matcher#matches方法进行匹配,从AntPathRequestMatcher的构造器可以看出,这里涉及到两个matcher(SubpathMatcher&SpringAntMatcher):

wKg0C2Qq6KKANX7tAABpoU5eJSc630.png

  如果 pattern 的值以 /**结尾并且不包含路径变量(即通配符{}),会使用SubpathMatcher,否则 matcher 赋值为 SpringAntMatcher 类的对象。

  • SubpathMatcher

  例如Pattern为/admin/**,此时会使用SubpathMacher#matches进行解析。具体实现如下:

  subpath从前面构造方法的调用可以知道主要是通过切割Pattern得到的(pattern.substring(0, pattern.length() - 3)),例如/admin/**切割后的subPath就是/admin。

  首先是统一转换成小写,然后如果请求的path以subpath开头,并且path的长度等于subpath的长度或者subpath长度后第一个字符是/则返回ture(满足/admin或者/admin/目录的访问方式):

wKg0C2Qq6VWATBb6AACAqb2M2iY905.png

  • SpringAntMatcher

  例如Pattern为/admin/*,此时会使用SpringAntMatcher#matches进行解析。具体实现如下:

  从构造方法可以看出实际上是调用的org.springframework.util.AntPathMatcher#match进行匹配:

wKg0C2Qq6YiAAQwsAAC3W7sS6pQ861.png

  核心方法是org.springframework.util.AntPathMatcher#doMatch,首先会调用tokenizePattern()方法将pattern分割成String数组,如果是全路径并且区分大小写,那么就通过简单的字符串检查,看看path是否有潜在匹配的可能,没有的话返回false:

wKg0C2Qq6baAEXQVAABGA3Y0BU579.png

  然后调用tokenizePath()方法将需要匹配的path分割成string数组,主要是通过java.util 里面的StringTokenizer来处理字符串:

wKg0C2Qq6eyAKj2mAAAmBYlIjk074.png

  接着将pathDirs和pattDirs两个数组从左到右开始匹配,这里涉及一些正则的转换还有通配符的匹配。以/admin/*为例,首先会调用getStringMatcher方法:

wKg0C2Qq6hiAdyVZAAAvjzAepDw002.png

  这里会调用AntPathStringMatcher的构造方法,实际上就是对Patten里的字符进行正则转换:

wKg0C2Qq6kCAQh9gAACp7VsCdQs761.png

  这里*最后会变成.*

wKg0C2Qq6oSAGu9qAAD78WTPEu4518.png

  最后封装java.util.regex.Pattern对象返回:

wKg0C2Qq6qWATvkAAAmMnfty0085.png

  最后调用matchStrings方法调用java.util.regex.compile#matcher进行匹配:

wKg0C2Qq6syADxYyAACPgj9akv8356.png

  Spring Framework的逻辑中,org.springframework.web.servlet.handler.AbstractHandlerMapping#initLookupPath方法中会初始化请求映射的路径,因为高版本默认使用的是PathPattern进行解析,所以会执行this.usesPathPatterns()为true时的逻辑:

wKg0C2Qq6waATeynAAB0bIcpQcY600.png

  以spring-webmvc-5.3.22为例,查看具体的解析过程:

  首先从request域中获取PATH_ATTRIBUTE属性的内容,然后使用defaultInstance对象进行处理:

wKg0C2Qq6yeAYv7lAABBYWOgtwo083.png

  这里会根据removeSemicolonContent的值(默认为true)确定是移除请求URI中的所有分号内容还是只移除jsessionid部分:

wKg0C2Qq60KADIw7AAAs6DW1g8c468.png

  这里逻辑会比较简单,缺少一些归一化的处理,例如并不会将//处理成/,也没有处理路径穿越。

  通过initLookupPath获取到路径后,会调用lookupHandlerMethod方法,根据请求的uri来找到对应的Controller和method。

  直接查看PathPattern的核心实现,主要在org.springframework.web.util.pattern.PathPattern#matches方法:

wKg0C2Qq63GAM0ASAABgFy03B6I049.png

  这里根据/将URL拆分成多个PathElement对象,然后根据PathPattern的链式节点中对应的PathElement的matches方法逐个进行匹配。举个例子:
  例如Pattern的第一个元素为/的话,会调用SeparatorPathElement的matches方法进行处理,结束后pathIndex++,继续遍历下一个元素进行处理:

wKg0C2Qq66qAHrYkAABnzXqVqN8579.png

  除此之外,根据不同Pattern的写法,还有很多PathElement:

  • WildcardPathElement(/api/*)
  • SingleCharWildcardedPathElement(/api/?)
  • WildcardTheRestPathElement(/api/**)
  • CaptureVariablePathElement(/api/{param})
  • CaptureTheRestPathElement(/api/{*param})
  • LiteralPathElement(/api/index)
  • RegexPathElement(/api/.*)

三、绕过场景

  根据前面的分析,利用解析的差异在某些条件下可能会存在绕过鉴权的风险。

  对于默认的Pattern模式,不开启DOTALL时候,在默认匹配的时候不会匹配\r \n 字符。

wKg0C2Qq7UCAccbgAAA3VH9mi4219.png

  根据前面的分析,AntPathRequestMatcher解析时,会调用AntPathStringMatcher的构造方法对Patten里的字符进行正则转换并封装成java.util.regex.Pattern对象返回,然后跟请求的Path进行匹配。不同版本间是存在差异的。

  • spring-core-5.3.21

wKg0C2Qq7ZCAMjBrAABK6lgyqrU118.png

  • spring-core-5.3.22

wKg0C2Qq7aSAUV2qAABOOCjhJvw176.png

  可以看到,在5.3.22版本之前,Pattern并没有配置dotall模式,从5.3.22版本开始,配置了dotall模式,此时的表达式.匹配任何字符,包括行结束符。

  结合前面的分析,结合实际场景进行Auth Bypass尝试。

  假设SpringSecurity配置如下:

protected void configure(HttpSecurity httpSecurity) throws Exception{
   httpSecurity.authorizeRequests().antMatchers("/admin/*").authenticated();
}

访问的Controller如下:

@GetMapping("/admin/*")
public String Manage(){
    return "manage";
}

  正常情况下/admin/page接口应该是需要认证以后才可以访问的:

wKg0C2Qq7gSAJs3yAABdV0wkgs106.png

  当使用高版本的Spring时,在进行路由解析时使用的是PathPatternParser。且当这个版本低于5.3.22时,AntPathRequestMatcher是无法匹配行结束符的。

  以5.3.21版本的Spring为例,使用\r或者\n(\r的URl编码为%0d,\n的URL编码为%0a)即可绕过当前的鉴权规则:

wKg0C2Qq7lqAGVz5AABvAWCEiHI518.png

  因为没有启用dotall模式,SpringSecurity匹配/admin/page%0a会失败,然后转由Spring的PathPattern进行解析,首先是admin字符匹配,当解析到*时会使用WildcardPathElement进行解析,若没有下一个Element元素的话,只要pathElements的元素个数和PathPattern中的元素个数一致都会返回true,也就是说page%0a跟*是可以成功匹配的:

wKg0C2Qq7pmARJk1AACZADMYq84455.png

  利用上述的差异即可达到auth Bypass的效果,当使用spring-core-5.3.22时,因为AntPathRequestMatcher在匹配时启用了dotall模式,此时的表达式.匹配任何字符,包括行结束符,无法auth Bypass:

wKg0C2Qq7r2AH2zPAABgx2MZfNo408.png

  同样是上面的SpringSecurity配置,当请求的Controllerr如下,也存在Auth Bypass的问题:

@GetMapping("/admin/{param}")
public String Manage(){
    /*return "Manage page";*/
    return "manage";
}

  当处理{param}时,PathPattern会使用CaptureVariablePathElement进行处理,因为通配符{}中没有正则,所以这里只需要pathElements的元素个数和PathPattern中的元素个数一致都会返回true:

wKg0C2Qq7uiAWJA1AACkvxZWVU370.png

wKg0C2Qq7vaAGrr0AAByIBcRupY181.png

PS:

  • 低版本的Spring使用的是AntPathMatcher,即使绕过了SpringSecurity也会因为解析差异找不到对应的Controller返回404。
  • SpringSecurity高版本的StrictHttpFirewall对\r或者\n(\r的URl编码为%0d,\n的URL编码为%0a)进行了拦截处理:

wKg0C2Qq7xCAFxIwAAAlxg0fI8U848.png

  根据前面的分析,对于SpringSecurity来说,在获取当前请求url时会对请求的url进行一定的处理,例如/admin/..最终会处理为/

wKg0C2Qq71qARY0KAACDvlWTI0A938.png

  而在Spring Framework的逻辑中,因为高版本默认使用的是PathPattern进行解析,所以会执行this.usesPathPatterns()为true时的逻辑,根据之前的分析,这里会根据主要是对请求URI中的所有分号内容进行处理,判断是移除全部部分还是只移除jsessionid部分,并没有处理编码,路径穿越符等内容:

wKg0C2Qq73mAdciAAB0bIcpQcY117.png

  同样是前面的场景:

  假设SpringSecurity配置如下:

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception{
   httpSecurity.authorizeRequests().antMatchers("/admin/*").authenticated();
}

  访问的Controller如下:

@GetMapping("/admin/*")
public String Manage(){
    return "manage";
}

  当尝试访问/admin/..时,AntPathRequestMatcher在处理时会认为当前请求的path是/,在进行匹配的时候因为请求的path为/,在isPotentialMatch方法处理时会认为没有潜在匹配的可能返回false:

wKg0C2Qq76mALNTkAABtq7YZC58270.png

  但是对于PathPattern而言,WildcardPathElement解析时若没有下一个Element元素的话,只要pathElements的元素个数和PathPattern中的元素个数一致都会返回true,也就是说..*是可以成功匹配的。

wKg0C2Qq8GOABBVCAAB7UqgejDs250.png

  同样的,如下的场景也会有绕过的风险:

  假设SpringSecurity配置如下:

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception{
   httpSecurity.authorizeRequests().antMatchers("/admin/**").authenticated();
}

  访问的Controller如下:

@GetMapping("/admin/**")
public String Manage(){
    return "manage";
}

  如果 pattern 的值以 /**结尾并且不包含路径变量(即通配符{}),会使用SubpathMatcher。匹配逻辑也比较简单,若请求的path以subpath开头,并且path的长度等于subpath的长度或者subpath长度后第一个字符是/则返回ture(满足/admin或者/admin/目录的访问方式)。这里//admin以及/admin/明显是不匹配的。

  但是PathPattern在解析/admin/**时候,在解析/**时会调用WildcardTheRestPathElement进行处理,因为PathPattern通配符只能定义在尾部(不能以/结尾),所以pathElements的元素个数大于PathPattern中的元素个数即可匹配,所以..是可以匹配上/**的,同样的由于SpringSecurity不能解析但是Spring Framework的PathPattern可以解析导致了Auth Bypass问题。

  PS:SpringSecurity高版本的StrictHttpFirewall对路径穿越符进行了拦截处理:

wKg0C2Qq8COAMmOdAAAyYhI921A395.png

四、其他

  实际上Spring官方很早就意识到解析差异带来的风险了。SpringSecurity还有一种匹配模式MvcRequestMatcher。

  参考https://docs.spring.io/spring-security/reference/servlet/integrations/mvc.html#mvc-requestmatcher

  其使用Spring MVC的HandlerMappingIntrospector来匹配路径并提取变量。相比AntPathRequestMatcher会更严谨。在一定程度解决了差异的问题。避免了前面AntPathRequestMatcher的绕过一些问题。

  同样是前面的例子,使用MvcRequestMatcher 后无法绕过鉴权逻辑:

wKg0C2Qq8OWATF8MAABv94Ueoo982.png

wKg0C2Qq8NKAAuIAACAekbSgcU313.png

wKg0C2Qq8bqAPVLmAAAmW6ZVaF4015.png

标签:解析,匹配,浅谈,admin,Spring,22602,SpringSecurity,PathPattern,CVE
From: https://www.cnblogs.com/SecIN/p/17516211.html

相关文章

  • 浅谈单调队列优化DP
    对于形如\[f_i=\max(f_{L≤j≤R}+w_i)\]的状态转移方程,也就是转移来自之前某个定长区间的最值,我们可以使用单调队列来维护区间最值,从而优化时间复杂度。烽火传递我们看到题目可以想到用\(f_i\)表示考虑到\(i\)这个烽火台,点第\(i\)个的合法方案中的最小代价那么可以想到......
  • Sudo堆溢出漏洞(CVE-2021-3156)复现
    背景介绍2021年1月26日,QualysResearchLabs在sudo发现了一个缺陷。sudo解析命令行参数的方式时,错误的判断了截断符,从而导致攻击者可以恶意构造载荷,使得sudo发生堆溢出,该漏洞在配合环境变量等分配堆以及释放堆的原语下,可以致使本地提权。环境搭建环境版本•ubuntu20......
  • 浅谈无线测温系统在高压开关柜中的应用
    罗轩志安科瑞电气股份有限公司上海嘉定201801摘要:高压开关柜是配电系统中重要的组成部分,其主要作用是控制电荷、分配电能和开断电流等,对维持系统的稳定性有一定的保障作用。将无线测温技术应用于高压开关柜,可以实现对其进行实时的动态监测,有助于相关工作人员根据高压开关柜的温度......
  • 浅谈智能照明控制管理系统的功能介绍
    罗轩志安科瑞电气股份有限公司上海嘉定201801摘要:智能照明控制系统较好地实现了智能控制、人性化照明和节能降耗的功能,使其在楼宇控制领域变得越来越重要,越来越受到人们的重视。本文介绍了智能照明控制系统的概念、特点、优势、发展方向等内容,并着重对智能照明控制系统的结构......
  • 浅谈 Kotlin 与 Java 互操作 (上)
    前言浅谈Kotlin与Java互操作(上)Kotlinis100%interoperablewithJavaandAndroidKotlin官网的一句标语,其旨意是表达kotlin的Interoperable-互操作特性互操作就表示Kotlin中可以调用Java的开放接口来访问成员属性和成员方法,同时在Java代码中也百分百兼容Kotlin......
  • 浅谈类 k 短路问题
    u群题题意:\(n\)个数,对于所有大小在\([L,R]\)内的子集求和并排序,求前\(k\)小子集的信息。排序,记数组为\(a_{1,\cdots,n}\)。先考虑\(L=R\)的情况。最小的子集一定是\(a_{1,\cdots,L}\),第二小则是将\(a_L\)改为\(a_{L+1}\),推广到更一般的情况——我们以\([1,L]\)......
  • UWB MAC层技术浅谈
    前言​ 对于大多数人来说,使用DW1000相关测距例程,按着教程实现简单的一对一测距不会有什么大问题。但当应用到实际场景后,现场环境同时出现几台,几十台设备时就会发现整套系统会出现严重的丢包、通信不良问题。而这其中的原因,是因为DW1000芯片只提供了UWBPHY层的实现,只完成了设备之......
  • 浅谈“信创”时代,恒辉软件发展前景
    随着中国的发展,很多技术因为一些原因越来越受制于人,尤其是上游核心技术。为了解决这个问题,中国明确了“数字中国”建设战略,抢占数字经济产业链制高点。自主创新与国产化已成为我国实现科技强国、经济强国的发展趋势与行业共识,中国要逐步建立基于自己的IT底层架构和标准,促使信创......
  • 浅谈基于企业微电网平台的食用菌工厂的能源管理--安科瑞张田田
    摘要:从食用菌生产经营者角度指出食用菌工厂化生产的产品生鲜属性、微生物培养的技术特点和竞争战略难以突破决定了成本控制是经营的核心。分析食用菌生产的成本构成,指出加强能源管理是节本增效的重要途径,从电费的分类和改善方式、灭菌的燃料选择和改善方法、未来能源可拓展方向(太阳......
  • 福昕Foxit PDF远程代码执行漏洞CVE-2023-27363分析与复现
    漏洞概述福建福昕软件开发股份有限公司是一家国际化运营的PDF电子文档解决方案提供厂商,提供文档的生成、转换、显示、编辑、搜索、打印、存储、签章、表单、保护、安全分发管理等涵盖文档生命周期的产品技术与解决方案。其下产品FoxitPDFReader和FoxitPDFEditor的javascript函......