Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Security and the class loader architecture

A look at the role played by class loaders in the JVM's overall security model

  • Print
  • Feedback

Page 5 of 6

Guarding restricted packages

Java allows classes in the same package to grant each other special access privileges that aren't granted to classes outside the package. So, if your class loader receives a request to load a class that by its name brazenly declares itself to be part of the Java API (for example, a class named java.lang.Virus), your class loader should proceed cautiously. If loaded, such a class could gain special access to the trusted classes of java.lang and could possibly use that special access for devious purposes.

Consequently, you would normally write a class loader so that it simply refuses to load any class that claims to be part of the Java API (or any other trusted runtime library) but that doesn't exist in the local trusted repository. In other words, after your class loader passes a request to the primordial class loader, and the primordial class loader indicates it can't load the class, your class loader should check to make sure the class doesn't declare itself to be a member of a trusted package. If it does, your class loader, instead of trying to download the class across the network, should throw a security exception.

Guarding forbidden packages

In addition, you may have installed some packages in the trusted repository that contain classes you want your application to be able to load through the primordial class loader, but that you don't want to be accessible to classes loaded through your class loader. For example, assume you have created a package named absolutepower and installed it on the local repository accessible by the primordial class loader. Assume also that you don't want classes loaded by your class loader to be able to load any class from the absolutepower package. In this case, you would write your class loader such that the very first thing it does is to make sure the requested class doesn't declare itself as a member of the absolutepower package. If such a class is requested, your class loader, rather than passing the class name to the primordial class loader, should throw a security exception.

The only way a class loader can know whether or not a class is from a restricted package, such as java.lang, or a forbidden package, such as absolutepower, is by the name of the class. Thus, a class loader must be given a list of the names of restricted and forbidden packages. Because the name of class java.lang.Virus indicates it is from the java.lang package, and java.lang is on the list of restricted packages, your class loader should throw a security exception if the primordial class loader can't load it. Likewise, because the name of class absolutepower.FancyClassLoader indicates it is part of the absolutepower package, and the absolutepower package is on the list of forbidden packages, your class loader should throw a security exception.

A security-minded class loader

A common way to write a security-minded class loader is to use the following four steps:

  1. If packages exist that this class loader is not allowed to load from, the class loader checks whether the requested class is in one of those forbidden packages mentioned above. If so, it throws a security exception. If not, it continues on to step two.

  2. The class loader passes the request to the primordial class loader. If the primordial class loader successfully returns the class, the class loader returns that same class. Otherwise it continues on to step three.

  3. If trusted packages exist that this class loader is not allowed to add classes to, the class loader checks whether the requested class is in one of those restricted packages. If so, it throws a security exception. If not, it continues on to step four.

  4. Finally, the class loader attempts to load the class in the custom way, such as by downloading it across a network. If successful, it returns the class. If unsuccessful, it throws a "no class definition found" error.


By performing steps one and three as outlined above, the class loader guards the borders of the trusted packages. With step one, it prevents a class from a forbidden package to be loaded at all. With step three, it doesn't allow an untrusted class to insert itself into a trusted package.

  • Print
  • Feedback

Resources
  • Previous "Under The Hood" articles:
  • The Lean, Mean Virtual Machine -- Gives an introduction to the Java virtual machine.
  • The Java Class File Lifestyle -- Gives an overview of the Java class file, the file format into which all Java programs are compiled.
  • Java's Garbage- Collected Heap -- Gives an overview of garbage collection in general and the garbage-collected heap of the Java virtual machine in particular.
  • Bytecode Basics -- Introduces the bytecodes of the Java virtual machine, and discusses primitive types, conversion operations, and stack operations in particular.
  • Floating Point Arithmetic -- Describes the Java virtual machine's floating-point support and the bytecodes that perform floating point operations.
  • Logic and Arithmetic -- Describes the Java virtual machine's support for logical and integer arithmetic, and the related bytecodes.
  • Objects and Arrays -- Describes how the Java virtual machine deals with objects and arrays, and discusses the relevant bytecodes.
  • Exceptions -- Describes how the Java virtual machine deals with exceptions, and discusses the relevant bytecodes.
  • Try-Finally -- Describes how the Java virtual machine implements try-finally clauses, and discusses the relevant bytecodes.
  • Control Flow -- Describes how the Java virtual machine implements control flow and discusses the relevant bytecodes.
  • The Architecture of Aglets -- Describes the inner workings of aglets, IBM's autonomous Java-based software agent technology.
  • The Point of Aglets -- Analyzes the real-world utility of mobile agents such as aglets, IBM's autonomous Java- based software agent technology.
  • Method Invocation and Return -- Describes the four ways the Java virtual machine invokes methods, including the relevant bytecodes.
  • Thread Synchronization -- Shows how thread synchronization works in the Java virtual machine. Discusses the bytecodes for entering and exiting monitors.
  • Java's Security Architecture -- Gives an overview of the security model built into the JVM and looks at the JVM's built-in safety features.