安全问题 正则表达式注入

正则表达式注入

数据被传递至应用程序并作为正则表达式使用。可能导致线程过度使用 CPU 资源,从而导致拒绝服务攻击。 

下述代码java中字符串的split, replaceAll均支持正则的方式, 导致CPU挂起.

1         final String input = "0000000000000000000000000000000000000000000000";
2         long startTime = System.currentTimeMillis();
3         System.out.println(input.split("(0*)*A"));
4         System.out.println("耗时:" + (System.currentTimeMillis() - startTime) + "ms");
  • 该正则的意思是说匹配器在输入的末尾并没有检测到”A”。现在外侧的限定符后退一次,内存的则前进一次,如此重复,无法得到结果。

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

修复方式

使用线程池 + Future, 限定执行时间, 并捕获异常.

复制代码
 1         ExecutorService service = Executors.newFixedThreadPool(1);
 2         Future result = service.submit(new Callable<Object>() {
 3             @Override
 4             public Object call() {
 5                 final String input = "0000000000000000000000000000000000000000000000";
 6                 return input.split("(0*)*A");
 7             }
 8         });
 9         service.shutdown();
10         System.out.println(result.get(5, TimeUnit.SECONDS));








不安全的随机数

Java API中提供了java.util.Random类实现PRNG(),该PRNG是可移植和可重复的,如果两个java.util.Random类的实例使用相同的种子,会在所有Java实现中生成相同的数值序列。

复制代码
 1         // Random对象r和s设置了相同的种子,因此 i == j 以及数组b[]和c[]的相应值是相等的。
 2         Random r = new Random(12345);
 3         int i = r.nextInt();
 4         byte[] b = new byte[4];
 5         r.nextBytes(b);
 6 
 7         Random s = new Random(12345);
 8         int j = s.nextInt();
 9         byte[] c = new byte[4];
10         s.nextBytes(c);
复制代码

修复方式

使用更安全的随机数生成器,如java.security.SecureRandom类。

1         SecureRandom number = SecureRandom.getInstance("SHA1PRNG");
2         System.out.println(number.nextInt()  + "  " + number.nextInt());
原文地址:https://www.cnblogs.com/yelongsan/p/9284639.html