1.1 权限控制的本质
一般来说,为了防止越权操作,通常会结合filter进⾏相关接⼝的鉴权操作。其中不不外乎就是对每⼀个接口(通俗来说就是我们的URI/URL)进行业务梳理,然后判断当前URI/URL是否具有相应的业务权限。
1.2 常见权限控制的实现
一般情况下,通常是获取到当前URI/URL,然后跟需要鉴权的接口进行⽐对,或者直接结合startsWith()或者endsWith()方法,设置对应的校验名单。
例如下⾯的过滤器实现,以/login开头的不需要校验(登陆业务每个人都可以访问),所有.do/.action结尾的接⼝均需要做登陆检查,防止未授权访问等。
String uri = request.getRequestURI();if(uri.endsWith(".do")||uri.endsWith(".action")) {
//检测当前用户是否登陆User user =(User) request.getSession().getAttribute("user");if(user==null|| "".equals(user)) {
errorResponse(response, paramN, "未授权访问");return;}}
但是,在Java中获取当前request中的URI/URL通常会使用request.getRequestURL()和request.getRequestURI()这两个方法,但是如果没有进⾏相关的处理的话,有可能导致权限控制绕过的风险。
1.3 绕过方式
当权限过滤器获取当前request中的URI/URL使用request.getRequestURL()和request.getRequestURI()这两个方法时,可以考虑以下三种⽅式进行权限绕过:
1.3.1 非标准化绕过
相关场景:
例如/system/login开头的接口是白名单,不需要进行访问控制(登陆页面所有人都可以访问),其他接⼝都需要进⾏登陆检查,防止未授权访问:
String uri = request.getRequestURI();if(uri.startsWith("/system/login")) {
//登陆接口设置⽩白名单filterChain.doFilter(request, response);}else if(uri.endsWith(".do")||uri.endsWith(".action")) {
//检测当前⽤户是否登陆User user =(User) request.getSession().getAttribute("user");if(user==null|| "".equals(user)) {
errorResponse(response, paramN, "未授权访问");return;}}
相关效果如下:
当未登录直接访问UserInfoSearch.do接口时,显示未授权访问:
相关原理:
中间件在进⾏解析时,会对我们URI中的../进行相关处理从⽽得到相关的servlet。也就是说尝试对我们访问的URL引