...
This guideline is an instance of SEC03-J. Do not load trusted classes after allowing untrusted code to load arbitrary classes. Many examples also violate SEC00-J. Do not allow privileged blocks to leak sensitive information across a trust boundary.
Noncompliant Code Example (CVE-2013-0422)
Java 1.7.0u10 was exploited in January 2013 because of several vulnerabilities. One vulnerability in the MBeanInstantiator
class granted unprivileged code the ability to access any class regardless of the current security policy or accessability of the class. The MBeanInstantiator.findClass()
method could be invoked with any string and would attempt to return a Class
object. This method delegated its work to the loadClass()
method, whose source code is shown:
Code Block | ||||
---|---|---|---|---|
| ||||
/**
* Load a class with the specified loader, or with this object
* class loader if the specified loader is null.
**/
static Class<?> loadClass(String className, ClassLoader loader)
throws ReflectionException {
Class<?> theClass;
if (className == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("The class name cannot be null"),
"Exception occurred during object instantiation");
}
try {
if (loader == null)
loader = MBeanInstantiator.class.getClassLoader();
if (loader != null) {
theClass = Class.forName(className, false, loader);
} else {
theClass = Class.forName(className);
}
} catch (ClassNotFoundException e) {
throw new ReflectionException(e,
"The MBean class could not be loaded");
}
return theClass;
}
|
This method clearly delegates work to the Class.forName()
method. The forName()
method only checks the immediate caller, and since it is the (trusted) loadClass()
method, happily returns a sensitive Class
object.
Compliant Solution (CVE-2013-0422)
Oracle mitigated this vulnerability in Java 1.7.0p11 by adding an access check to the loadClass()
method. This access check ensures that the caller is permitted to access the class being sought:
Code Block | ||||
---|---|---|---|---|
| ||||
...
if (className == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("The class name cannot be null"),
"Exception occurred during object instantiation");
}
ReflectUtil.checkPackageAccess(className);
try {
if (loader == null)
...
|
Noncompliant Code Example
In this noncompliant code example a call to System.loadLibrary()
is embedded in a doPrivileged
block. This is insecure because a library can be loaded on behalf of untrusted code. In essence, the untrusted code's class loader may be able to indirectly load a library even though it lacks sufficient permissions to do so directly. After loading the library, untrusted code can call native methods from the library if those methods are accessible. This is possible because the doPrivileged
block stops security manager checks being applied to callers further up the execution chain.
...
Oracle Security Alert for CVE-2013-0422
Manion, Art, Anatomy of Java Exploits, CERT/CC Blog, January 15, 2013 2:00 PM
...