JavaWeb中的权限控制—过滤器&拦截器

admin 2021年5月6日04:19:57评论513 views字数 4426阅读14分45秒阅读模式

  在实际的系统开发中,经常涉及到权限校验的业务需求,例如低权限用户无法使用高权限用户的业务接口,未登陆的用户无法访问业务接口等,主要是通过过滤器&拦截器进行实现的。但是如果实现的过程中存在缺陷,那么就可能导致一系列的越权漏洞。

过滤器Filter

  Filter(过滤器)是Servlet2.3规范中定义的一种小型的、可插入的Web组件,其作用是拦截Servlet容器的请求和响应,控制客户端和服务端进行的数据交换。一个web应用程序中可以注册多个Filter,若有多个Filter对某个Servlet程序的访问过程进行拦截,当针对该Servlet的访问请求到达时,多个Filter将组合成一个Filter链(过滤器链)。根据各个Filter在web.xml的映射顺序,或者注解的命名进行相应顺序的拦截。在权限校验中经常会使用到过滤器,包括常见的权限控制框架Shiro也是基于过滤器进行拓展的。

过滤器简单实现

  过滤器的实现必须实现javax.servlet.Filter接口,该接口定义了init()、doFilter()和destory()三个方法:
  首先通过init()方法结合FilterConfig接口进行初始化参数,然后创建过滤器,当拦截到相关的请求时,doFilter()方法就会执行,可多次执行,通过重写该方法对我们业务的request和response进行预处理,然后通过FilterChain对象的doFilter方法可以放行请求,将当前的请求响应在整个过滤器链中向下传递。最后销毁Filter时自动调用destory()方法。
  整个Filter的生命周期大致是:随着服务器启动创建,关闭而销毁。下面是一个简单的Filter样例:

JavaWeb中的权限控制—过滤器&拦截器

  最后将对应的filter在web.xml或者通过注解进行相关的配置即可。

定位过滤器

  主要是通过检索web.xml以及搜索@WebFilter关键字进行定位。

web.xml

  在web.xml中通过进行过滤器的注册,然后通过<filter-mapping>进行过滤器映射。例如:

JavaWeb中的权限控制—过滤器&拦截器

  此处配置所起的作用是,此filter对所有的jsp页面都有设置字符集的效果。

  需要关注个几个元素:

| 相关元素 | 具体意义 |
| -------------------- | :------------------------------------------------ |
| | 设置该过滤器对应的filter类 |
| | 设置filter所拦截的请求路径(filter关联的URL样式) |

  通过可以快速的定位到具体的过滤器实现,进行相关的审计,然后主要是指定对应过滤器的URL匹配模式。例如以下案例就是对system目录下的所有对象都有过滤拦截效果,那么就可以结合实际的权限需要进行检查了。

JavaWeb中的权限控制—过滤器&拦截器

@WebFilter注解

  Servlet3.0提供了@WebFilter 用于将一个类声明为过滤器,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为过滤器:

java
@WebFilter(filterName="PermissionFilter",urlPatterns="/*")
public class PermissionFilter implements Filter{
//......
}

  同样的@WebFilter 的urlPatterns属性也是用于指定对应过滤器的URL匹配模式。例如上例中就是对所有的对象都会具有过滤拦截的效果。

审计要点

  • urlPatterns是否覆盖全面
  • 具体实现是否存在缺陷
  • 获取接口的方式
  • 获取用户信息凭证的方式
  • ......

相关案例

  例如下面是一个校验用户登陆状态防止未授权访问的filter具体实现:

java
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;
}
}

  其获取接口的方式是通过request.getRequestURI()实现的,同时没有进行相应的规范化处理,那么可以使用类似.action;bypass的方式进行接口访问,从而绕过上述防止未授权访问的安全控制。具体的接口获取方法分析可参考:过滤器设计缺陷导致权限绕过
  继续看一个例子,这里获取用户信息凭证的方式存在缺陷,通过从cookie中获取对应的userId,判断是普通用户还是VIP客户,进行对应的权限划分。但是cookie字段的内容是可控的,可以通过修改cookie字段中对应的userId,达到越权访问的目的。:

java
//vip视频访问控制
if(actionUrl.startsWith("/vip/videoCourse")){
String user_id = cookie.getCookie("userId");
String userType = new UserDao().verifyUserTypes(user_id);
if(userType=="0"||userType.equals(0)){
//没有观看vip视频的权限,抛出权限异常,返回登陆页面
......
}
//进行实际的业务处理
......
}

拦截器Interceptor

  Java中的拦截器是动态拦截action调用的对象。在实现上基于Java的反射机制,属于AOP的一种应用,作用类似于过滤器,但是拦截器只能对Controller请求进行拦截,对其他的直接访问静态资源的请求无法拦截处理

拦截器简单实现

  一般可以结合Web框架来实现,例如Spring中提供的支持,可以通过实现接口 HandlerInterceptor或者继承HandlerInterceptorAdapter类来实现。
  实现接口需要实现其中所有方法,继承抽象类则一般实现preHandle方法即可。下面的拦截器是通过结合Spring框架,实现接口 HandlerInterceptor实现的:

JavaWeb中的权限控制—过滤器&拦截器

  当然也可以实现Spring 的HandlerInterceptor接口进行定义:

JavaWeb中的权限控制—过滤器&拦截器

  然后把创建的拦截器配置到springMVC配置文件中就可以了。

定位拦截器

通过Interceptor关键字检索

  无论是通过继承还是实现Interceptor接口的方式,都存在Interceptor关键字,可以直接搜索进行检索。

通过相关配置

  在创建好拦截器相关的类以后,会到配置文件中进行相关的配置,以SpringMVC为例,在xml文件会有相关的定义:

JavaWeb中的权限控制—过滤器&拦截器
  通过bean属性即可定位拦截器的具体实现,通过通过mapping,exclude-mapping还可以定位对应的urlPatterns细节。
  当然也可以通过注解的方式结合相关的方法进行配置:

java
@EnableWebMvc
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
@Autowired
private AdminInterceptor adminInterceptor
......
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册第两个个拦截器,excludePathPatterns是取消拦截的路径
registry.addInterceptor(adminInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin/login");
}
......
}

审计要点

  跟filter类似,但是由于拦截器对于直接访问静态资源的请求无法拦截处理,所以需要额外关注静态资源的业务(例如PDF、Excel导出下载等)。

  • urlPatterns是否覆盖全面
  • 具体实现是否存在缺陷
  • 获取接口的方式
  • 获取用户信息凭证的方式
  • ......
  • 静态资源访问

相关案例

  例如如下的拦截器配置:

JavaWeb中的权限控制—过滤器&拦截器

  LoginedInterceptor的具体实现:

java
public class LoginedInterceptor extends HandlerInterceptorAdapter{
@Override
public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception{
HttpSession session = request.getSession();
Object loginuser = session.getAttribute(SystemBaseConstant.LOGIN_USER_ID);
if(loginuser==null||"".equals(loginuser)){
request.getRequestDispathcer("/login").forward(request,response);
return false;
}
}
return true;
}

  拦截器主要对接口进行登录检查,防止未授权访问。但是/sysUserQuery这个接口是在白名单内的,看接口名称应该是系统用户查询:

java
@RequestMapping({"/sysUserQuery"})
public String sysUserQuery(String id){
User user = this.userService.query(id);
return user.toString();
}

  可以看到直接传递id直接进行用户信息查询了,即使是跟其他系统进行数据校验,也应该绑定token凭证。防止未授权接口访问。
  再比如静态资源的管理,例如Web应用的一些下载模版、内部资料等下载目录,filter实现时仅仅只需要startsWith("/admin")就可以进行拦截管控了,但是拦截器缺没办法拦截,很可能存在静态资源未授权访问的缺陷。
  此外,获取接口的方式还有获取权限校验凭证的方式的检查思路跟过滤器filter也是类似的。

相关推荐: SQL注入的总结

有人的地方就有江湖,有数据库的地方就会有SQL注入(有可能......) 那么言归正传,SQL注入这个漏洞是怎么造成的呢??? 当客户端提交的数据没有被作处理或者没有被转义直接就带入数据库,那么就会造成我刚刚说的SQL注入漏洞,攻击者通过构造不同的SQL语句来…

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年5月6日04:19:57
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   JavaWeb中的权限控制—过滤器&拦截器https://cn-sec.com/archives/246403.html