前言:
在Java中,正則的使用需要謹慎,好的正則可以方便我們的代碼,但是不好的正則,可能成為黑客攻擊的漏洞。類似本例子的正則,黑客可以組織不同的匹配字符,使得校驗不過,耗盡服務器資源(資源耗盡攻擊)。詳見正則的狀態機原理。
1.說明:2018/8/17:
校驗輸入字符串是否合規,允許:100000000000^145^1^1000.00| 100000000000^145^1^1000.00| ....
如此序列(100000000000^145^1^1000.00|)必須滿足1-18個,19個則失敗。
寫正則:reg = ^(\\d{12}\\^\\d{3}\\^[123456]{1}\\^\\d+[\\.\\d+]*\\|){1,18}$
代碼:
String regex = "^(\\d{12}\\^\\d{3}\\^[123456]{1}\\^\\d+[\\.\\d+]*\\|){1,18}$"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(prove); if (!matcher.matches()) { return false; } return true;
2.問題:
在測試案例中含有18個序列,正常通過。在案例增加到19個序列時,程序卡死。
3.分析:
正則循環次數過多!導致資源耗盡或死循環。
4.解決方法:
減少正則校驗的循環次數,改為程序循環!,直接傳遞切割好的數組,再對數組進行循環。
代碼:
String[] proves = accountProve.split("\\|"); if (proves.length > 18 || proves.length < 1) { return false; } for (String prove : proves) { String regex = "^(\\d{12}\\^\\d{3}\\^[123456]{1}\\^\\d+[\\.\\d+]*)$"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(prove); if (!matcher.matches()) { return false; } } return true;