filter 不过滤静态文件_原创干货 | 过滤器常见安全问题

9e9cb0419b8dc8c8400cb1d9ab1a7c6a.png0 1相关背景

过滤器是处于客户端与服务器资源文件之间的一道网,在访问资源文件之前,通过一系列的过滤器对请求进行修改、判断等,把不符合规则的请求在中途拦截或修改。也可以对响应进行过滤,拦截或修改响应。通过Filter技术对request、JSP、静态资源等进行拦截,从而实现一些安全需求,例如常见的权限访问控制、SQL注入和XSS敏感内容过滤、响应信息编码处理,设置响应头等。但是如果相关的过滤器存在缺陷,那么可能导致相关的安全防护无效,进而攻击者可以绕过过滤器对Web应用进行攻击。

0 2Filter简单工作原理 过 滤 器在web程序启动时进行加载,发送的request请求先到过滤器,过滤器判断我们的request内容是否符合设定的规则,符合再将request请求发送到web资源,当web资源处理完后,将response响应再丢给过滤器,最后过滤器将对应的响应信息给到用户。

c9a3bef7c6f1c211d2641486f521de0c.png

01Filter常见安全设计问题 结合实际代码审计遇到的场景,常见问题如下:

获取数据的方式:

既然要对request中的参数内容进行检测,那么首先肯定是要获取到对应的内容了,常见过滤器获取request请求内容的方式如下,通过HttpServletRequest中的getParameter()或者getParameterNames()方法进行获取参数内容:

560d0d331873234c0e17bef0fd1abf46.png

或者使用HttpServletRequestWrapper重写request请求参数的function(这里是重写了getParameterNames()):

d344a480bfd0ea3994da88d14f876cc0.png

但是使用request.getParameterNames()方法并不能覆盖所有的数据提交方式,同理,request.getParameter()亦然。

在request中主要是根据Content-type进行判断提交的方式,服务器根据其值将body体里的内容恢复成相应的数据结构。常见的Content-type类型如下:
  • application/x-www-form-urlencoded(最常见的POST提交方式,以键值对的方式进行传输,例如key=value)

  • application/json(JSON提交方式)

  • text/xml(XML提交方式)

  • multipart/form-data(文件上传表单,上传文件功能会用到)

使用上面常见过滤器中的 request.getParameterNames()&&request.getParameter()方法明显是无法覆盖上面全部类型的,那么如果只是简单的配置安全过滤器,那么可能会存在过滤器失效或者防护不足的问题。

JSON格式支持比常见的键值对复杂得多的结构化数据,所以在实际的开发场景里会经常用到。但是

request.getParameterNames()&&request.getParameter()方法明显是无法获取并解析application/json这种提交方式的。 举例说明,利用上述方式搭建Web环境,SQL注入也是常见的安全漏洞,预编译是很好解决该漏洞的方案,但是类似Orderby排序、动态表名等场景明显无法进行预编译,那么过滤器过滤敏感输入就是很好的一种解决方案了。

正常情况下是可以拦截application/x-www-form-urlencoded这种常见的提交方式并进行SQL注入过滤检测的:

b53f0a6d750debc40fdd03d0a098be0a.png

但是如果某个业务接口是JSON提交的话,上述的过滤器明显无法获取到request提交的内容并进行安全检查,这里使用报错注入成功避开过滤器获得了当前数据库的user:

35f0a55752dd3fee333ace89ba6ce599.png

再者,对于multipart/form-data这种数据类型上述过滤器明显也是无法获取request提交内容的。那么如果此时存在类似批量Excel导入(例如批量新建用户)的业务功能点的话,那么上述过滤器也无法进行安全防护,例如excel导入的内容输出在页面上并未进行编码转译,xss过滤器由于无法获取到multipart/form-data类型的数据,导致存储型XSS。

当然了,即使我们的requet请求均以application/x-www-form-urlencoded类型进行传统的key-value方式提交,可能由于一些框架的特性,也会存在对应的绕过风险。

以Java常见的SpringMVC为例:

简单来说,服务器层面获取到前端请求后,接下来SpringMVC会收到服务器传来的request请求,此时若请求为上传POST型,SpringMVC会继续调用相关的解析器对其进行解析处理。以下是搭建的相关环境:

正常情况下的数据包如下,查询业务,查询tkswifty成功返回对应的员工信息:

959fd519916a64ecbf40ecd343ed3c40.png

尝试以multipart方式提交(上传POST型),同样的服务器接收到参数后,相关框架也进行了解析并完成了查询业务:

473f0ba2c843acc3a46bbfca10ae7168.png

前面也提到了。对于multipart/form-data这种数据类型上述使用request.getParameterNames()&&request.getParameter()方法进行内容获取的过滤器明显是对写入的恶意poc无法进行检测处理的。

  • 过滤的规则内容:

过滤器中的安全规则检查,本质就是黑名单/白名单。不符合安全规则的则进行拦截。

以xss的过滤器为例,因为xss在实际开发场景中比较杂乱,因为在view层写入的位置很多,而且各个场景下的编码转译方式都不一样,很多时候无法兼顾每一个位置,所以更多的会选用过滤器进行XSS的防护。但是如果过滤器内容存在缺陷的话,攻击者可以绕过过滤器对Web应用进行攻击。

在github上找了一个现成的过滤器,进行相关的安全审计,该过滤器主要是对用户的输入进行检查,如果命中相关的正则便将对应的内容替换为空,例如输入

85137ca4cc3c475a54c38c16732ccb76.png

相关的规则乍一看还是很全的,过滤的内容包括相关的协议、标签、js函数以及相关的js事件。

以下面场景为例,分析上面的过滤器内容,尝试绕过进行xss攻击:

0119d3a9eb73bab90c40ca2d5a69f31f.png

该场景的xss攻击的思路如下:
  1. 闭合双引号然后结合js事件(例如onclick)进行触发;
  2. 闭合双引号然后尝试新建标签进行触发。

以下针对上面两种思路进行尝试:

首先尝试闭合双引号然后写入js事件进行触发,输入tkswifty”οnclick=”alert(1),其中alert被过滤了:

979a5d2c5057f930f5bedf1698347449.png

查看过滤器规则,把window对象以及alert过滤了:

be1828e6b3789b55210900c8d575f417.png

但是不妨碍使用prompt进行触发,如果要进一步尝试利用的话,也可以通过这种方式来调用windows对象:window['alert'](window['document']['cookie']):

da301abd2505c1f9590866d93e8fee7d.png

而且可以发现,虽然规则里过滤了相关的js事件(例如onclick、oncopy),但是这种场景下似乎并没有生效,规则如下:

a3b2ab87ceeca2613ff93f851219d8cd.png

可以看到正则是这类的输入会直接过滤掉,对于非

917c46050abed5654aa99d41952f8b3b.png

所以针对闭合双引号然后结合js事件的场景该过滤器的过滤内容存在缺陷,可简单绕过。

然后是闭合双引号然后尝试新建标签进行触发,根据前面的分析,直接写入

36d788d2bf14167a53cf8fd3c5e71050.png

正确的顺序应该是解码过滤器应该在xss过滤器之前,一次解码后,在xss过滤器中通过request.getParameter()得到的就是

再比如现在很多app都是加密传输的,很多情况下会在过滤器进行数据包的解密,然后再提交给对应的Controller进行业务处理,如果对应的类似xss过滤器是在解密过滤器之前的话,也是无法起到防护效果的。

0 3总结

过滤器作为安全开发中常用的方法,并不是简单的复制黏贴就可以达到对应的效果的,其内容规则、顺序、获取数据的方式等细节都是值得推敲考究的。

0554ccc80c88abcdb586118b27a3535b.gif f0ca17f50b19415c5373107d85212a2e.gif 12beee7cdb158be69f836348ab192768.png f0ca17f50b19415c5373107d85212a2e.gif扫码关注我们“ 在看”的永远18岁~ db9caa3fc27fa14bcdc59af8de6f9496.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于Java过滤器Filter的使用,我可以给您一些详解。 Java过滤器Filter是一种Web组件,它可以对请求(request)和响应(response)进行过滤和处理。通常情况下,我们使用Java过滤器Filter来对请求进行预处理,或者对响应进行后处理。这样可以减轻Servlet的负担,提高程序的可重用性。 Java过滤器Filter的使用非常简单,只需要创建一个Java类,实现javax.servlet.Filter接口,并重写doFilter方法即可。在doFilter方法中,我们可以对请求和响应进行处理,然后将它们传递给下一个过滤器或Servlet。 下面是一个简单的Java过滤器Filter的示例,它可以过滤掉某个包的请求: ``` public class PackageFilter implements Filter { private String packageName; @Override public void init(FilterConfig filterConfig) throws ServletException { packageName = filterConfig.getInitParameter("packageName"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; String path = req.getServletPath(); if (path.startsWith(packageName)) { // 过滤掉指定包的请求 return; } chain.doFilter(request, response); } @Override public void destroy() { // do nothing } } ``` 在这个例子中,我们通过init方法获取了过滤器初始化参数packageName,然后在doFilter方法中判断请求路径是否以packageName开头,如果是,则直接返回,否则将请求传递给下一个过滤器或Servlet。 使用Java过滤器Filter可以方便地对请求和响应进行处理,从而提高程序的可重用性和性能。同时,Java过滤器Filter还可以通过配置文件进行灵活的配置,满足不同场景的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值