java 正则死循环_Java 正则表达式漏洞

由于工作原因,一直没有时间把在线上遇到的问题总结一下。还好,今天我来了。

废话少说了。

主要说一下“java 正则表达式中的一个漏洞”,详细问题描述

目前使用 1.6 和 1.7 都没有修补该漏洞。

来个白话文吧

案例代码 Test.java

1 final Pattern pattern = Pattern.compile("(0*)*A");2 final String input = "0000000000000000000000000000000000000000000000";3

4 long startTime =System.currentTimeMillis();5 Matcher matcher =pattern.matcher(input);6 System.out.println(matcher.find());7 System.out.println("Regex took:" + (System.currentTimeMillis() - startTime) + "ms");

意思是说匹配器在输入的末尾并没有检测到”A”。现在外侧的限定符后退一次,内存的则前进一次,如此重复,无法得到结果。

因此,匹配器逐步回退,并尝试所有的组合以找出匹配符号。它最终将返回(没有匹配的结果),但是该过程的复杂性是指数型的(输入中添加一个字符加倍了运行时间)

赶紧查看cpu占用率(top)

bb761ea44f537acdc7d6f02164e0dcac.png

尼玛呀,这都上99.9了。吓死宝宝了。赶紧看看这货到底是啥?

查看进程信息(ps -ef | grep 17837)(17837为进程id)

2a8bdb35f840f882fd840523dd7c962c.png

这不是我写的那个测试类吗?看来漏洞复现了。赶紧看一下这货暂用CPU的情况

ps mp 17837 -o THREAD,tid,time (注意逗号之间不要加空格)

a1c853f2f949e9ce2d28ed95a57df21b.png

这家伙已经占用CPU快一个小时了。应该是死循环了。赶紧看看出啥幺蛾子了。

这时我们可以通过jdk提供的工具查看具体的堆栈信息(jstack )

jstack 17837

#4/13日 发现可以使用 kill -3 pid 来查看dump信息。高兴

12ef2b09fc5afd2b08ab0e36664cddc0.png

问题复现了。这就是我们说说的jdk正则的漏洞。

主要表象就是长时间占用CPU,应用表象就是:页面访问白板,无响应。

具体的解决方案,我不赘述网上其他人说的c,Python的解决方法(因为我不会吗。。。。。)

1)优化正则,别写的那个正则别人一看就吓一跳。其实业务没有那么简单

2)使用线程,并且捕获异常,详见 http://stackoverflow.com/questions/910740/cancelling-a-long-running-regex-match

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值