Apache shiro RegExPatternMatcher 权限绕过漏洞 (CVE-2022-32532)

漏洞描述

2022年6月29日,Apache 官方披露 Apache Shiro (CVE-2022-32532)权限绕过漏洞。
Apache Shiro中使用RegexRequestMatcher进行权限配置,且正则表达式中携带"."时,未经授权的远程攻击者可通过构造恶意数据包绕过身份认证,导致配置的权限验证失效。

相关介绍

Apache Shiro 是一个功能强大且易于使用的 Java 安全框架,它可以执行身份验证、授权、加密和会话管理,可以用于保护任何应用程序——从命令行应用程序、移动应用程序到最大的 web 和企业应用程序。

影响版本

安全版本:Apache Shiro = 1.9.1
受影响版本:Apache Shiro < 1.9.1

漏洞

贴上我遇到的漏洞截图,如下图:
在这里插入图片描述
根据提示将相关包的版本升级至1.9.1,打包程序并部署。
发现还是会扫描出该漏洞,依次升级至1.10.01.11.01.12.0,直到1.12.0版本该漏洞未出现了。

本以为是简单的版本升级,结果发现登录请求里的createToken之类的方法每次都执行2次;

跟踪代码

  • Shiro配置类ShiroConfig中的shiroFilterFactoryBean方法
    @Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();// Shiro的核心安全接口,这个属性是必须的shiroFilterFactoryBean.setSecurityManager(securityManager);// 身份认证失败,则跳转到登录页面的配置shiroFilterFactoryBean.setLoginUrl(loginUrl);// 权限认证失败,则跳转到指定页面shiroFilterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);// Shiro连接约束配置,即过滤链的定义LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();// 对静态资源设置匿名访问...........return shiroFilterFactoryBean;}
  • 进一步追踪
private void applyGlobalPropertiesIfNecessary(Filter filter) {this.applyLoginUrlIfNecessary(filter);this.applySuccessUrlIfNecessary(filter);this.applyUnauthorizedUrlIfNecessary(filter);if (filter instanceof OncePerRequestFilter) {((OncePerRequestFilter)filter).setFilterOncePerRequest(this.filterConfiguration.isFilterOncePerRequest());}}public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof Filter) {log.debug("Found filter chain candidate filter '{}'", beanName);Filter filter = (Filter)bean;this.applyGlobalPropertiesIfNecessary(filter);this.getFilters().put(beanName, filter);} else {log.trace("Ignoring non-Filter bean '{}'", beanName);}return bean;}

从上面方法可以看出来postProcessBeforeInitialization方法在bean初始化的时候去执行, 将自定义的登录过滤器中的setFilterOncePerRequest设置为了ShiroFilterConfiguration实例中给定的值;
其值默认是false,未启用OncePerRequestFilter的只执行一次机制

OncePerRequestFilter 类的核心方法(1.9.0和1.12.0版本的区别)

  • Apache Shiro = 1.9.0时,OncePerRequestFilter类源码
package org.apache.shiro.web.servlet;import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public abstract class OncePerRequestFilter extends NameableFilter {private static final Logger log = LoggerFactory.getLogger(OncePerRequestFilter.class);public static final String ALREADY_FILTERED_SUFFIX = ".FILTERED";private boolean enabled = true;public OncePerRequestFilter() {}public boolean isEnabled() { return this.enabled; }public void setEnabled(boolean enabled) { this.enabled = enabled; }public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {String alreadyFilteredAttributeName = this.getAlreadyFilteredAttributeName();if (request.getAttribute(alreadyFilteredAttributeName) != null) {log.trace("Filter '{}' already executed.  Proceeding without invoking this filter.", this.getName());filterChain.doFilter(request, response);} else if (this.isEnabled(request, response) && !this.shouldNotFilter(request)) {log.trace("Filter '{}' not yet executed.  Executing now.", this.getName());request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);try {this.doFilterInternal(request, response, filterChain);} finally {request.removeAttribute(alreadyFilteredAttributeName);}} else {log.debug("Filter '{}' is not enabled for the current request.  Proceeding without invoking this filter.", this.getName());filterChain.doFilter(request, response);}}protected boolean isEnabled(ServletRequest request, ServletResponse response) throws ServletException, IOException {return this.isEnabled();}protected String getAlreadyFilteredAttributeName() {String name = this.getName();if (name == null) {name = this.getClass().getName();}return name + ".FILTERED";}/** @deprecated */@Deprecatedprotected boolean shouldNotFilter(ServletRequest request) throws ServletException {return false;}protected abstract void doFilterInternal(ServletRequest var1, ServletResponse var2, FilterChain var3) throws ServletException, IOException;
}
  • Apache Shiro = 1.12.0时,OncePerRequestFilter 类源码
package org.apache.shiro.web.servlet;import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public abstract class OncePerRequestFilter extends NameableFilter {private static final Logger log = LoggerFactory.getLogger(OncePerRequestFilter.class);public static final String ALREADY_FILTERED_SUFFIX = ".FILTERED";private boolean enabled = true;private boolean filterOncePerRequest = false;public OncePerRequestFilter() {}public boolean isEnabled() { return this.enabled; }public void setEnabled(boolean enabled) { this.enabled = enabled; }public boolean isFilterOncePerRequest() { return this.filterOncePerRequest; }public void setFilterOncePerRequest(boolean filterOncePerRequest) {this.filterOncePerRequest = filterOncePerRequest;}public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {String alreadyFilteredAttributeName = this.getAlreadyFilteredAttributeName();if (request.getAttribute(alreadyFilteredAttributeName) != null && this.filterOncePerRequest) {log.trace("Filter '{}' already executed.  Proceeding without invoking this filter.", this.getName());filterChain.doFilter(request, response);} else if (this.isEnabled(request, response) && !this.shouldNotFilter(request)) {log.trace("Filter '{}' not yet executed.  Executing now.", this.getName());request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);try {this.doFilterInternal(request, response, filterChain);} finally {request.removeAttribute(alreadyFilteredAttributeName);}} else {log.debug("Filter '{}' is not enabled for the current request.  Proceeding without invoking this filter.", this.getName());filterChain.doFilter(request, response);}}protected boolean isEnabled(ServletRequest request, ServletResponse response) throws ServletException, IOException {return this.isEnabled();}protected String getAlreadyFilteredAttributeName() {String name = this.getName();if (name == null) {name = this.getClass().getName();}return name + ".FILTERED";}/** @deprecated */@Deprecatedprotected boolean shouldNotFilter(ServletRequest request) throws ServletException {return false;}protected abstract void doFilterInternal(ServletRequest var1, ServletResponse var2, FilterChain var3) throws ServletException, IOException;
}

对比两个版本代码的发现:Apache Shiro = 1.12.0版本时,doFilter方法第三行代码增加了&& filterOncePerRequest判断,这个值就是通过ShiroFilterConfiguration > ShiroFilterFactoryBean一路传进来的,而且他是在构造ShiroFilterFactoryBean之后执行的, 比自定义Filter的构造时间要晚, 所以尝试在自定义过滤器的构造方法或者postxxx, afterxxx之类的方法中去设置为true都是没用的。

只能是构造ShiroFilterFactoryBean对象时, 设置其配置属性来解决问题。

解决方法

  • 创建ShiroFilterFactoryBean的时候, 给他一个ShiroFilterConfiguration实例对象, 并且设置这个实例的setFilterOncePerRequest(true)
    @Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){ShiroFilterConfiguration config = new ShiroFilterConfiguration();//全局配置是否启用OncePerRequestFilter的只执行一次机制config.setFilterOncePerRequest(Boolean.TRUE);ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setShiroFilterConfiguration(config);// Shiro的核心安全接口,这个属性是必须的shiroFilterFactoryBean.setSecurityManager(securityManager);// 身份认证失败,则跳转到登录页面的配置shiroFilterFactoryBean.setLoginUrl(loginUrl);// 权限认证失败,则跳转到指定页面shiroFilterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);// Shiro连接约束配置,即过滤链的定义LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();// 对静态资源设置匿名访问...........return shiroFilterFactoryBean;}

总结

Apache Shiro = 1.9.0以前的版本,OncePerRequestFilter过滤器子类型默认只执行一次,
现在可以通过全局配置来选择是否启用OncePerRequestFilter的只执行一次机制.

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

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

相关文章

【医疗图像处理软件】重要功能集合

很高兴在雪易的CSDN遇见你 &#xff0c;给你糖糖 欢迎大家加入雪易社区-CSDN社区云 一起挑战150岁生命线&#xff01; 前言之前&#xff1a;从事医疗器械行业使我们更加关注自己的健康&#xff0c;每天看着髋膝关节置换的手术视频&#xff0c;我们会更加爱护自己的膝盖。同…

服务断路器_服务雪崩解决方案之服务降级

什么是服务降级 两种场景: 当下游的服务因为某种原因响应过慢&#xff0c;下游服务主动停掉一些不太重要的业务&#xff0c;释放出服务器资源&#xff0c;增加响应速度&#xff01;当下游的服务因为某种原因不可用&#xff0c;上游主动调用本地的一些降级逻辑&#xff0c;避免…

http基础教程(超详细)

HTTP HTTP 一 、基础概念 请求和响应报文URL 二、HTTP 方法 GETHEADPOSTPUTPATCHDELETEOPTIONSCONNECTTRACE 三、HTTP 状态码 1XX 信息2XX 成功3XX 重定向4XX 客户端错误5XX 服务器错误 四、HTTP 首部 通用首部字段请求首部字段响应首部字段实体首部字段 五、具体应用 连接管理…

vue_Delete `␍`eslint(prettier/prettier)

Delete ␍eslint(prettier/prettier) 错误的解决方案 问题背景 在Windows笔记本上新拉完代码&#xff0c;在执行pre-commit时&#xff0c;出现如下错误&#xff1a; Delete ␍eslint(prettier/prettier)问题根源 罪魁祸首是git的一个配置属性&#xff1a;core.autocrlf 由于…

小程序编译器性能优化之路

作者 | 马可 导读 小程序编译器是百度开发者工具中的编译构建模块&#xff0c;用来将小程序代码转换成运行时代码。旧版编译器由于业务发展&#xff0c;存在编译慢、内存占用高的问题&#xff0c;我们对编译器做了一次大规模的重构&#xff0c;采用自研架构&#xff0c;做了多线…

C++——安装环境、工具

一、进入官网下载 Visual Studio 下载地址&#xff1a;https://visualstudio.microsoft.com/zh-hans/ 二、安装 三、安装完后如果出现window SDK 下载失败&#xff0c;可自行下载&#xff0c;如果没有请跳过这一步 Window SDK 官方地址&#xff1a;https://developer.microsoft…

详解Java执行groovy脚本的两种方式

详解Java执行groovy脚本的两种方式 文章目录 详解Java执行groovy脚本的两种方式介绍记录Java执行groovy脚本的两种invokeFunction:invokeMethod:以下为案例&#xff1a;引入依赖定义脚本内容并执行运行结果&#xff1a;例如把脚本内容定义为这样&#xff1a;执行结果就是这样了…

Java 大厂八股文面试专题-JVM相关面试题 类加载器

Java 大厂八股文面试专题-设计模式 工厂方法模式、策略模式、责任链模式-CSDN博客 JVM相关面试题 1 JVM组成 1.1 JVM由那些部分组成&#xff0c;运行流程是什么&#xff1f; 难易程度&#xff1a;☆☆☆ 出现频率&#xff1a;☆☆☆☆ JVM是什么 Java Virtual Machine Java程序…

Oracle VM VirtualBox安装并下载安装CentOS7

Oracle VM VirtualBox安装并下载安装CentOS7 Oracle VM VirtualBox下载CentOS创建虚拟机 Oracle VM VirtualBox VM下载链接 https://www.oracle.com/cn/virtualization/virtualbox/ 点击链接直接下载就行&#xff0c;下载完默认安装或者更改一下安装目录。 下载CentOS http://…

竞赛 基于生成对抗网络的照片上色动态算法设计与实现 - 深度学习 opencv python

文章目录 1 前言1 课题背景2 GAN(生成对抗网络)2.1 简介2.2 基本原理 3 DeOldify 框架4 First Order Motion Model5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于生成对抗网络的照片上色动态算法设计与实现 该项目较为新颖&am…

面试题08.05.递归算法

递归乘法。 写一个递归函数&#xff0c;不使用 * 运算符&#xff0c; 实现两个正整数的相乘。可以使用加号、减号、位移&#xff0c;但要吝啬一些。 示例1: 输入&#xff1a;A 1, B 10输出&#xff1a;10示例2: 输入&#xff1a;A 3, B 4输出&#xff1a;12提示: 保证乘法…

【解决】Unity3D中无法在MQTT事件中执行Animator

问题原因&#xff1a; 解决方法&#xff1a; 解决过程 1、在 Unity 中创建一个名为 MainThreadDispatcher 的脚本&#xff0c;用于处理主线程操作。 using System.Collections.Generic; using UnityEngine;public class MainThreadDispatcher : MonoBehaviour {private stati…

JDK、JRE 和 JVM 的区别和联系

三者关系 就这三者的关系而言&#xff0c;jvm是jre的子集&#xff0c;jre是jdk的子集&#xff0c;具体关系如下图&#xff1a; Java的执行流程 对于一个Java程序&#xff0c;其执行流程大致如下&#xff1a; 开发人员使用JDK编写和编译Java源代码&#xff0c;生成Java字节码文…

【SQL server】数据库入门基本操作教学

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 前言 数据库是计算机系统中用于存储和管理数据的一种软件系统。它通常由一个或多个数据集合、管理系统和应用程序组成&#xff0c;被广泛应用于企业、政府和个人等各种领域。目前常用的数…

安防视频平台EasyCVR视频调阅全屏播放显示异常是什么原因?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

KF32A学习笔记(一):工程导入、编译烧录方法(KF32 IDE+ KF32 PRO)

目录 概述KF32 IDE打开现有项目工程1.工程导入2.编译工程3.下载程序 KF32 PRO 概述 本文主要是对KF32A150芯片程序的编译、烧录方法进行说明。针对开发过程中的编译烧录和无代码情况下的烧录两种场景&#xff0c;需要安装ChipON PRO KF32和ChipON IDE KF32两个上位机工具&…

LLM之Colossal-LLaMA-2:Colossal-LLaMA-2的简介、安装、使用方法之详细攻略

LLM之Colossal-LLaMA-2&#xff1a;Colossal-LLaMA-2的简介、安装、使用方法之详细攻略 导读&#xff1a;2023年9月25日&#xff0c;Colossal-AI团队推出了开源模型Colossal-LLaMA-2-7B-base。Colossal-LLaMA-2项目的技术细节&#xff0c;主要核心要点总结如下: >> 数据处…

最新ChatGPT网站系统源码+支持GPT4.0+支持AI绘画Midjourney绘画+支持国内全AI模型

一、SparkAI创作系统 SparkAi系统是基于很火的GPT提问进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT系统&#xff1f;小编这里写一个详细图文教程吧&a…

Learn Prompt- Midjourney案例:动漫设计

使用 Midjourney 生成动漫有两种方法&#xff1a;使用Niji模式或使用标准的 Midjourney 模型。Niji V5 是 Midjourney 的动漫专用模型。它建立在标准 Midjourney 模型的全新架构之上&#xff0c;更擅长生成命名的动漫角色。Niji V4于2023年12月发布&#xff0c;Niji V5于2023年…

数据结构--快速排序

文章目录 快速排序的概念Hoare版本挖坑法前后指针法快速排序的优化三数取中法小区间用插入排序 非递归的快速排序 快速排序的概念 快速排序是通过二叉树的思想&#xff0c;先设定一个值&#xff0c;通过比较&#xff0c;比它大的放在它的右边&#xff0c;比它小的放在它的左边…