Skip to content
New issue

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

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

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants