漏洞成因
Shiro拦截器
Shiro框架通过拦截器功能来实现对用户访问权限的控制和拦截。Shiro中常见的拦截器有anon,authc等拦截器。
1.anon为匿名拦截器,不需要登录就能访问,一般用于静态资源,或者移动端接口
2.authc为登录拦截器,需要登录认证才能访问的资源。
用户可以在Shiro.ini编写匹配URL配置,将会拦截匹配的URL,并执行响应的拦截器。从而实现对URL的访问控制,URL路径表达式通常为ANT格式。如下配置,访问 /index.html主页的时候,Shiro将不会对其进行登录判断,anon拦截器不需要登录就能进行访问。而对于/user/xiaoming 等 /user/xiaogang等接口,authc拦截器将会对其进行登录判断,有登录认证才能访问资源。
[urls]
/index.html = anon
/user/** = authc
Shiro的URL路径表达式为Ant 格式,路径通配符支持?***
?:匹配一个字符
*:匹配零个或多个字符串
**:匹配路径中的零个或多个路径
这里粗略解释一下,当路径为/xxx/..和拦截规则里的/xxx/**匹配成功,通过校验,成功转向后方的Spring Boot . 从而进行了绕过
其中*表示匹配零个或多个字符串,/可以匹配/hello,但匹配不到/hello/因为通配符无法匹配路径。假设/hello接口设置了authc拦截器,访问/hello将会被进行权限判断,如果请求的URI为/hello/呢,/*URL路径表达式将无法正确匹配,放行。然后进入到spring(Servlet)拦截器,spring中/hello形式和/hello/形式的URL访问的资源是一样的。
本实验环境 使用docker完成复现,公网
这个应用中对URL权限的配置如下:
@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端口

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


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

修复
升级1.5.2版本及以上
修改了requestURI的获取方式,经过更准确的解析获取