正則表達式注入
數據被傳遞至應用程序並作為正則表達式使用。可能導致線程過度使用 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());