Shiro认证绕过CVE-2020-1957

漏洞成因

Shiro拦截器

Shiro框架通过拦截器功能来实现对用户访问权限的控制和拦截。Shiro中常见的拦截器有anon,authc等拦截器。

1
2
3
1.anon为匿名拦截器,不需要登录就能访问,一般用于静态资源,或者移动端接口

2.authc为登录拦截器,需要登录认证才能访问的资源。

用户可以在Shiro.ini编写匹配URL配置,将会拦截匹配的URL,并执行响应的拦截器。从而实现对URL的访问控制,URL路径表达式通常为ANT格式。如下配置,访问 /index.html主页的时候,Shiro将不会对其进行登录判断,anon拦截器不需要登录就能进行访问。而对于/user/xiaoming 等 /user/xiaogang等接口,authc拦截器将会对其进行登录判断,有登录认证才能访问资源。

1
2
3
[urls]
/index.html = anon
/user/** = authc

Shiro的URL路径表达式为Ant 格式,路径通配符支持?***

1
2
3
?:匹配一个字符
*:匹配零个或多个字符串
**:匹配路径中的零个或多个路径

这里粗略解释一下,当路径为/xxx/..和拦截规则里的/xxx/**匹配成功,通过校验,成功转向后方的Spring Boot . 从而进行了绕过

其中*表示匹配零个或多个字符串,/可以匹配/hello,但匹配不到/hello/因为通配符无法匹配路径。假设/hello接口设置了authc拦截器,访问/hello将会被进行权限判断,如果请求的URI为/hello/呢,/*URL路径表达式将无法正确匹配,放行。然后进入到spring(Servlet)拦截器,spring中/hello形式和/hello/形式的URL访问的资源是一样的。

本实验环境 使用docker完成复现,公网

这个应用中对URL权限的配置如下:

1
2
3
4
5
6
7
8
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
chainDefinition.addPathDefinition("/login.html", "authc"); // need to accept POSTs from the login form
chainDefinition.addPathDefinition("/logout", "logout");
chainDefinition.addPathDefinition("/admin/**", "authc");
return chainDefinition;
}

1.访问环境8080端口

image-20250326154808543

2.当访问地址/admin/会被重定向到login.php

image-20250326154940212

image-20250326155227524

3.构造恶意请求/xxx/..;/admin/ ,绕过权限校验,到达管理员界面

image-20250326155755134

修复

https://github.com/apache/shiro/commit/3708d7907016bf2fa12691dff6ff0def1249b8ce#diff-98f7bc5c0391389e56531f8b3754081aR139

升级1.5.2版本及以上

修改了requestURI的获取方式,经过更准确的解析获取

参考链接

https://www.freebuf.com/vuls/231909.html

https://xz.aliyun.com/news/7876?time__1311=Yqjx0DuDgiuDlOzG7DyDAOAWuboToD&u_atoken=0428e47a997e4a01d1ccb7c1af771093&u_asig=0a47314717429912626914864e0099


Shiro认证绕过CVE-2020-1957
https://ydnd.github.io/2025/03/26/Shiro认证绕过CVE-2020-1957/
Author
IE
Posted on
March 26, 2025
Licensed under