Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added January exploit details as NCCE/CS pair

...

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
bgColor#ffcccc
langjava
/**
 * 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
bgColor#ccccff
langjava
...
    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.

...

[API 2011] Class ClassLoader

Oracle Security Alert for CVE-2013-0422
Manion, Art, Anatomy of Java Exploits, CERT/CC Blog, January 15, 2013 2:00 PM

...