Java 2 Class Loading Mechanism

The class loading mechanism plays a critical role in Java security since the class loader is responsible for locating and fetching the class files, consulting the security policy, and defining the appropriate permissions associated with the class object.

In JDK 1.1, local code and correctly signed remote code were generally trusted to have full access to all vital system resources, such as the file system itself, while unsigned remote code was not trusted and could access only limited resources. A security manager was responsible for determining which resource accesses were allowed. For this reason each application, such as a Web browser or a Web server, had to write its own subclasses of SecurityManager and ClassLoader.

Java 2 has simplified the development process:

•SecurityManager is no longer an abstract class and can be instantiated or subclassed. Most of its methods now make calls to methods in class AccessController, which provides the access control functions in Java 2. This greatly simplifies the writing of new SecurityManager subclasses.

• A new powerful subclass of ClassLoader has been created in Java 2. It is called SecureClassLoader and is found in the package java.security . The distinguishing feature of a SecureClassLoader is that it associates a protection domain with each class that it loads. SecureClassLoader has a protected constructor, so its real use is to provide the basis for the development of other class loaders. When creating a custom class loader, one can subclass from the SecureClassLoader class or its subclasses, depending on the particular need.

To automatically invoke the security subsystem, a Java application is started from the command line of a native operating system with some additional command line arguments. We have shown one example of how applications can be subjected to security restrictions in Java 2 by specifying additional command line arguments.

When a Java code starts executing, the Java run time creates an instance of SecureClassLoader, which in turn is used to locate and load the class file of the code. A subclass of the security manager is created and installed in the Java run time. The main() method, in the case of an application, is then called with the command line arguments; the init() method is called in the case of an applet or a servlet.

SecureClassLoader is used to safely and correctly load classes into the Java run time. How does the SecureClassLoader ensure secure loading of classes?
1. First, SecureClassLoader searches for classes in the correct order. The correct order starts with the most trusted classes. Therefore, when the JVM needs a class, SecureClassLoader first looks for files referenced by the class path of the JVM, or the boot class path. This ensures that classes within the core Java API will not be superseded by classes loaded from the network or any other location.
2. If not found in the JVM class path, the locations of the installed extensions are searched.
3. Finally, the locations defined by the application class path are searched.

Once the class file has been loaded into the JVM, SecureClassLoader assigns the appropriate protection domain to the class file. The following list explains how SecureClassLoader does this:
1. When SecureClassLoader loads a class into the JVM, it also creates the code source for the class from the code base URL and any digital certificate(s) used to sign the code.
2. The code source is then used to locate the protection domain for the class. The protection domain contains the Permission objects that have been granted to the class. The information contained in the protection domain and the permissions granted to the code source are used in determining access control during run time.
3. Once a Java program starts to run, SecureClassLoader assists the JVM in loading other classes required to run the program. These classes are also assigned the appropriate protection domains based on their code source.

“Notice that another new class, java.net.URLClassLoader, extends SecureClassLoader to provide a general purpose class loader to load class files from a list of local class file directories or HTTP-based URLs.”

Run-Time Access Controls

At various points during a Java program’s execution, access to protected resources is requested. This includes network I/O attempts, local file I/O, attempts to create a new ClassLoader or access to a program-defined resource. To verify whether the running program is allowed to perform the operation, the library routine makes a call to the method SecurityManager.checkPermission(). This method takes a Permission object argument and determines whether or not it is granted to the current thread.

Each thread in the JVM contains a number of stack frames. Simply stated, these frames contain the method instance variables for each method called in the current thread. The method checkPermission() walks back through the current thread’s stack frames, getting the protection domain for each of the classes on the thread’s stack. As each protection domain in the thread stack is located, the permission to check is compared to the Permission objects contained in the protection domain. For each stack frame, if the checked permission matches one of the Permission objects in the protection domain, testing of the permissions continues with the protection domain of the next stack frame (class) on the stack.

This testing repeats until the end of the stack is reached. That is, all of the classes in the thread have the permission to perform the operation. Thus, the access control check succeeds, typically meaning that the requested operation is able to proceed. If the checked permission is not granted to all classes on the stack (there is no appropriate Permission object in all of the class’s ProtectionDomain objects), then a SecurityException is thrown, and access to the resource is denied.