威脅描述
程序會(huì)調(diào)用解析 double
類型的方法废封,這會(huì)導(dǎo)致線程被掛起。
威脅說明
在實(shí)施 java.lang.Double.parseDouble()
及相關(guān)方法時(shí)出現(xiàn)漏洞闷哆,會(huì)導(dǎo)致在解析 [2^(-1022) - 2^(-1075) : 2^(-1022) - 2^(-1076)]
范圍內(nèi)的任意數(shù)字時(shí)掛起線程噪生。此缺陷可被攻擊者用于執(zhí)行拒絕服務(wù) (DoS) 攻擊苹享。
例 1:下列代碼使用了易受攻擊的方法。
Double d = Double.parseDouble(request.getParameter("d"));
攻擊者可以發(fā)送 d 參數(shù)值位于該范圍(例如 0.0222507385850720119e-00306
)內(nèi)的請求弛矛,致使程序在處理該請求時(shí)被掛起够吩。
該漏洞在 Java 版本 6 Update 23 及更早版本中存在。Java 版本 6 Update 24 或更高版本不存在該漏洞丈氓。
修復(fù)建議
方案1:升級(jí)JDK至1.6 Update 24 以上周循,若JDK已經(jīng)是1.6 Update 24以上,該類型漏洞可以關(guān)閉万俗。
方案2:臨時(shí)方案
public class ConvertDouble {
private final static Pattern NUMBER_PATTERN = Pattern.compile("^([+-]?\\d*\\.?\\d*([eE][+-]?)?\\d*).*");
public static double parseDouble(String value) {
String normalString = normalizeDoubleString(value);
int offset = normalString.indexOf('E');
BigDecimal base;
int exponent;
if (offset == -1) {
base = new BigDecimal(value);
exponent = 0;
} else {
base = new BigDecimal(normalString.substring(0,offset));
exponent = Integer.parseInt(normalString.charAt(offset+ 1) == '+'?
normalString.substring(offset +2) :
normalString.substring(offset +1));
}
returnbase.scaleByPowerOfTen(exponent).doubleValue();
}
public static String normalizeDoubleString(String strValue) {
// Clean-up string representation so that it could be understood
// by Java's BigDecimal. Not terribly efficient for now.
// 1. MRI allows d and D as exponent separators
strValue = strValue.replaceFirst("[edD]","E");
// 2. MRI allows underscores anywhere
strValue = strValue.replaceAll("_", "");
// 3. MRI ignores the trailing junk
strValue = NUMBER_PATTERN.matcher(strValue).replaceFirst("$1");
return strValue;
}
}