zoukankan      html  css  js  c++  java
  • Java 正则表达式漏洞

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

    废话少说了。

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

    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6988218

    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507

    目前使用 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)

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

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

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

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

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

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

    jstack 17837

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

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

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

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

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

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

  • 相关阅读:
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
    Careercup
  • 原文地址:https://www.cnblogs.com/liuhouhou/p/5378853.html
Copyright © 2011-2022 走看看