XSS防御的一些坑

2022-06-02 18:02:40 浏览数 (1)

为什么要总结这一篇文章?防止大家少走一些弯路。Spring应用程序里面XSS防御,该怎么做?网上文章一大把,但是看起来感觉都有很大的问题。

至于什么是XSS在这里不解释了,常见的XSS攻击有三种:反射型XSS攻击、DOM-based型XSS攻击、存储型XSS攻击。我们在这里讲:反射型XSS攻击,DOM-based型怎么做。存储型XSS攻击一定要校验好上传文件的类型,不能只校验文件后缀名,使用文件头信息去校验。

在实际Web开发中,我们需要过滤或者编码页面传递给后台的特殊字符,防止XSS跨站脚本攻击。这个时候我们可以想到使用过滤器或者拦截器,至于为什么要选择Filter而不是Interceptor?我认为有两点:Filter依赖于Servlet容器,而Interceptor不依赖于Servlet容器;Filter对几乎所有的请求起作用,而Interceptor只能对action请求起作用。我先抛几个问题,希望可以引来不同的声音。

是否所有的请求都要去防御XSS?

比如一些比较复杂的富文本切带权限控制的没必要,我们可以通过配置文件设置一下白名单。建议使用绝对路径去控制,加上支持Ant风格-请求路径的一种匹配方式。

Header是否需要增加XSS防御?

需要比如通过头信息Referer去钓鱼欺骗,但是header的传递需要重新add,要不然下游是获取不到当前XssHttpServletRequestWrapper的头信息的。

代码语言:javascript复制
 XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
 HttpServletRequest httpServletRequest = xssRequest.getOrgRequest();
 Enumeration<?> er = httpServletRequest.getHeaderNames();
 String headerName;
 while (er.hasMoreElements()) {
     headerName = er.nextElement().toString();
     xssRequest.addHeader(headerName, httpServletRequest.getHeader(headerName));
  }
  chain.doFilter(xssRequest, response);

是否只需要重写基本方法?

@RequestParam是使用getParameterValues方法来获取参数值的,而不是getParameter方法。

所以只需要重写HttpServletRequestWrapper的getParameterValues方法,就可以解决上述无法覆盖的问题了。

getParameterNames,getParameterValues和getParameterMap等方法,也需要覆盖。同理,例如我们通过header中进行权限校验的时候,getHeaderNames方法也可能需要覆盖,不仅仅是覆盖getHeader方法,否则可能在某些特定场景下相关的参数值无法进入Filter,导致过滤缺失。

Controller里面使用Servlet,需要使用对应的ServletWrapper?

不需要,使用HttpServletRequest对象即可。request到达servlet之前拦截HttpServletRequest对象,也可以在服务方法转移控制后拦截HttpServletResponse对象。

责任链模式,通过httpServletRequest的装饰类HttpServletRequestWrapper来实现,只需要在装饰类中按照需要重写其对应的方法即可。

仅靠一个Filter能防御住XSS吗?

不能够完全能,需要运维和前后端一起配置,贴近实际业务那些是能过滤的,那些是不能过滤的。但是如果遇见混淆万能的XSS脚本咋办?好像没有什么好的解决方案。我们只要防御到大多数的攻击即可,尽量多加点缓解措施,提高利用成本,提高攻击门槛。

任何一个东西,不要总停留在网上现成的解决方案,勿在浮沙筑高台,实践是检验真理的唯一标准。


每周一句:人生没有太多的时间让自己原地打转及浪费,避开策略和目标的细节就是耍流氓。大家五一快乐!

0 人点赞