Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: major edits to the intro, corrected the intro flow which seemed confused, please review

The classloader architecture is key when it comes to preventing untrusted code from impersonating trusted code and isolating the two from each other. Most software systems use different classloaders to load untrusted and trusted code sources to provide the isolation guarantees.

A classloader that loads untrusted code should be forbidden from interacting with trusted code that invokes the following API methods.

Java uses security managers and security policies together to prevent untrusted code from performing privileged operations. In standard installations, a restrictive systemwide security policy prevents instantiation of sensitive classes such as java.lang.ClassLoader, for example, in the context of a web browser. It remains critically important to ensure that untrusted code cannot indirectly use the privileges of trusted code to perform privileged operations.

Most APIs install security manager checks to prevent such privilege escalation attacks; some APIs fail to do so. These APIs are tabulated in the following table. 

APIs

java.lang.Class.forName

java.lang.Package.getPackage(s)

java.lang.Runtime.load

java.lang.Runtime.loadLibrary

java.lang.System.load

java.lang.System.loadLibrary

java.sql.DriverManager.getConnection

java.sql.DriverManager.getDriver(s)

java.sql.DriverManager.deregisterDriver

java.util.ResourceBundle.getBundle

The loadLibrary and load APIs throw a security exception when the caller lacks permission to dynamically link the library code. These APIs are nevertheless listed as unsafe because they use the immediate caller's class loader to find and load the requested library. Moreover, because the loadLibrary and load APIs are typically used from within a doPrivileged block, unprivileged callers can directly invoke it without requiring any special permissions.

These APIs perform tasks using the immediate caller's class loader. They can be exploited when they are invoked indirectly by untrusted code or when they accept tainted inputs from untrusted code.

Classes that have the same defining class loader exist in the same namespace but may have different privileges, depending on the security policy. Security vulnerabilities can arise when trusted code coexists with untrusted code that was loaded by the same defining class loader. In this case, the untrusted code can freely access members of the trusted code according to their declared accessibility. When the trusted code uses any of the tabulated APIs, no security manager checks are carried out (with the exception of loadLibrary and load).

Security vulnerabilities can also arise even when untrusted code has been loaded by a class loader instance that is distinct from the class loader used to load the trusted invocation of these API methods is allowed by the trusted code's classloader, however, untrusted code's classloader may lack these privileges. Failure to comply with this guideline may result in compromise of the trust boundary between the trusted and untrusted code. When the untrusted code's class loader delegates to the trusted code's class loader, the untrusted code has visibility to the trusted code according to the declared visibility of the trusted code. In the absence of such a delegation relationship, the class loaders would ensure namespace separation; consequently, the untrusted code would be unable to observe members or to invoke methods belonging to the trusted code. Such a delegation model is imperative to many Java implementations and frameworks so the best advice is to avoid exposing these methods to untrusted code.

Consider, for example, an attack scenario where untrusted code that is attempting to load a privileged class. Its class loader is permitted to delegate the class loading to the trusted class's class loader. This can result in privilege escalation, because the untrusted code's class loader may lack permission to load the requested privileged class. Further, if the trusted code accepts tainted inputs, the trusted code's class loader could load additional privileged — or even malicious — classes on behalf of the untrusted code.

Classes that have the same defining class loader exist in the same namespace but may have different privileges, depending on the security policy. Security vulnerabilities can also arise when trusted code coexists with untrusted code (or less privileged code) that was loaded by the same defining class loader. In this case, the untrusted code can freely access members of the trusted code according to their declared accessibility. When the trusted code uses any of the tabulated APIs, no security manager checks are carried out (with the exception of loadLibrary and load).

A security sensitive class loader typically employs the security manager to enforce a security policy. For example, the applet class loader ensures that an applet cannot directly invoke methods of classes present in the com.sun.* package. A security manager check ensures that specific actions are allowed or denied depending on the privileges of the caller methods on the call stack (the privileges are associated with the code source that encompasses the class). A security manager complements the security offered by the classloader architecture and does not supersede it. Consequently, APIs that perform security manager checks may still violate this guideline at the class loader level when exposed to untrusted callers.

With the exception of loadLibrary() and load() methods, the tabulated APIs do not perform any security manager checks. Because the loadLibrary and load APIs are typically used from within a doPrivileged block, unprivileged callers can directly invoke them without requiring any special permissions. That means that the security manager checks are curtailed at the immediate caller and the entire call stack is not examined, resulting in no enhanced security. Accepting tainted inputs from untrusted code and allowing them to be used by these APIs may also expose vulnerabilities.

 

This guideline is an instance of SEC04-J. Protect sensitive operations with security manager checks. Many examples also violate SEC00-J. Do not allow privileged blocks to leak sensitive information across a trust boundary.

...