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) #519

Closed
m4ra7h0n opened this issue Sep 29, 2023 · 2 comments

Comments

@m4ra7h0n
Copy link

使用版本:

SaToken version <= 1.36.0

复现步骤:

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/** or /admin/*
(然后写一个登录接口,一个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/**") // or "/admin/*"
    public String getPassword() {
        return "flag{m4ra7h0n}";
    }
}

Login first(http://localhost:8081/user/doLogin?username=zhang&password=123456)
(首先登录)
image

Then access: /admin/anything
(然后访问/admin/anything)
image

修复建议

参考CVE-2023-20860

@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
@click33
Copy link
Collaborator

click33 commented Oct 1, 2023

收到

@click33
Copy link
Collaborator

click33 commented Oct 1, 2023

这个问题我本地测试了一下,和 @RequestMapping("/admin/**") // or "/admin/*" 没有关系,
造成此问题的原因 只是因为开发者在写路由匹配规则时没有在最前面加 / ,所以才没有被匹配到。

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

换成这样写就能匹配到

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

因为没有在路由匹配符的最前面加 / ,而没有被拦截命中,我认为这并不违反直觉,
这应该视为开发者的写法失误,而不是框架的漏洞问题。

如有你还有其他看法,欢迎继续评论。

最后,感觉提交反馈。

@click33 click33 closed this as completed Oct 16, 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