下载地址:https://github.com/dromara/Sa-Token
使用文档:https://sa-token.cc/doc.html#/start/example
使用request.getRequestURI() 获取url:
更改com.pj.satoken.SaTokenConfigure#getSaServletFilter函数,
放行js后缀的路径和登录入口/acc/doLogin,其他的路径均需登录之后才能访问,
.addInclude("/**").addExclude("/**/*.js", "/acc/doLogin")
// 认证函数: 每次请求执行
.setAuth(obj -> {
// SaManager.getLog().debug("----- 请求path={} 提交token={}", SaHolder.getRequest().getRequestPath(), StpUtil.getTokenValue());
// 检查用户是否登录
if (!StpUtil.isLogin()) {
// 如果未登录,抛出异常或返回拒绝访问的错误
throw new SaTokenException("没有登录");
}
})
cn.dev33.satoken.filter.SaPathCheckFilterForServlet#doFilter
这里会判断路径是否合法,
cn.dev33.satoken.fun.strategy.SaCheckRequestPathFunction,
过滤了./和/和.的url编码,%25是为了过滤二次编码,
cn.dev33.satoken.filter.SaServletFilter#doFilter,
全局过滤器会根据com.pj.satoken.SaTokenConfigure#getSaServletFilter中自定义的规则来判断哪些路径需要权限认证,
接着进入notMatch函数匹配请求的路径是否符合不需要权限认证的情况,
之后利用request.getRequestURI()获取我们请求的路径去匹配我们自定义的规则,
request.getRequestURI(),他直接获取我们请求的路径,
使用../和url编码会绕过以下规则,
.addInclude("/").addExclude("/public/"),
payload如下:/public/../acc/isLogin,
但是上图会先过滤路径的./和/和.的url编码,因此以上方式就无效了,
那么如果规则是.addInclude("/").addExclude("//*.js", "/acc/doLogin"),
(如果写的是判断后缀的规则,那么就能利用分号绕过)
payload如下:/acc/isLogin;.js,
就会造成权限绕过,因为分号在url中是对参数进行分割的,刚好匹配ant规则,url也不会被分号影响,
最终就会访问到/acc/isLogin,
效果如下,
正常情况下/acc/doLogin放行,
正常情况下拦截,
使用分号绕过,
因此可以在过滤函数中将分号和其url编码也添加到其中进行检测
作者:tj
链接:https://xz.aliyun.com/t/15604
原文始发于微信公众号(船山信安):Sa-Token对url过滤不全存在的风险点
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论