Java's security architecture

An overview of the JVM's security model and a look at its built-in safety features

1 2 Page 2
Page 2 of 2

Why security?



  • Reading or writing to the local disk
  • Making a network connection to any host, except the host from which the applet came
  • Creating a new process
  • Loading a new dynamic library and directly calling a native method


The sandbox defined

Traditionally, you had to trust software before you ran it. You achieved security by being careful only to use software from trusted sources, and by regularly scanning for viruses just to make sure things were safe. Once some software got access to your system, it had full rein. If it was malicious, it could do a great deal of damage to your system because there were no restrictions placed on the software by the runtime environment of your computer. So, in the traditional security scheme, you tried to prevent malicious code from ever gaining access to your computer in the first place.

The sandbox security model makes it easier to work with software that comes from sources you don't fully trust. Instead of security being established by requiring you to prevent any code you don't trust from ever making its way onto your computer, the sandbox model lets you welcome code from any source. But as it's running, the sandbox restricts code from untrusted sources from taking any actions that could possibly harm your system. The advantage is you don't need to figure out what code you can and can't trust, and you don't need to scan for viruses. The sandbox itself prevents any viruses or other malicious code you may invite into your computer from doing any damage.

The sandbox is pervasive

If you have a properly skeptical mind, you'll need to be convinced that a sandbox has no leaks before you trust it to protect you. To make sure the sandbox has no leaks, Java's security model involves every aspect of its architecture. If there were areas in Java's architecture in which security was weak, a malicious programmer (a "cracker") potentially could exploit those areas to "go around" the sandbox. To understand the sandbox, therefore, you must look at several different parts of Java's architecture and understand how they work together.

The fundamental components responsible for Java's sandbox are:

  • Safety features built into the Java virtual machine (and the language)
  • The class loader architecture
  • The class file verifier
  • The security manager and the Java API

The sandbox is customizable

One of the greatest strengths of Java's security model is that two of the four components shown in the above list, the class loader and the security manager, are customizable. To customize a sandbox, you write a class that descends from java.lang.SecurityManager. In this class, you override methods declared in the superclass that decide whether or not to allow particular actions, such as writing to the local disk. You will want to establish a custom SecurityManager when you are using custom class loaders to load class that you don't fully trust.

As a developer, you may never need to create your own customized sandbox -- you can often make use of sandboxes created by others. When you write and run a Java applet, for instance, you make use of a sandbox created by the developers of the Web browser that hosts your applet.

The remainder of this article will discuss the Java virtual machine's safety features. Subsequent articles in this series will describe the other three prongs of Java's security architecture: class loaders, class verification, and the security manager.

Safety features built into the JVM


  • Type-safe reference casting
  • Structured memory access (no pointer arithmetic)
  • Automatic garbage collection (can't explicitly free allocated memory)
  • Array bounds checking
  • Checking references for null


Safety features and security




Unspecified memory layout



Safety is built in



The problem of native methods

Basically, when you call a native method, Java's security sandbox becomes dust in the wind. First of all, the guarantees of robustness don't hold for native methods. Although you can't corrupt memory from a Java method, you can from a native method. But most important, native methods don't go through the Java API (native methods provide a means of going around the Java API), so the security manager isn't checked before a native method attempts to do something that could be potentially damaging. Of course, this is often how the Java API itself gets anything done. Many Java API methods may be implemented as native methods, but the native methods used by the Java API are "trusted."

Thus, once a thread gets into a native method, the security policy established inside the Java virtual machine -- no matter what is is -- doesn't apply anymore to that thread, so long as that thread continues to execute the native method. This is why the security manager includes a method that establishes whether or not a program can load dynamic libraries, which are necessary for invoking native methods. If untrusted code is allowed to load a dynamic library, that code could maliciously invoke native methods that wreak havoc with the local system. If a piece of untrusted code is prevented by the security manager from loading a dynamic library, it won't be able to invoke an untrusted native method. Its malicious intent will be thwarted. Applets, for example, aren't allowed to load a new dynamic library and therefore can't install their own new native methods. They can, however, call methods in the Java API, methods that may be native but that are always trusted.

When a thread invokes a native method, that thread leaps outside the sandbox. The security model for native methods therefore is the same traditional approach to computer security described earlier: You have to trust a native method before you call it.

Structured error handling

One final mechanism that is built into the Java virtual machine and that contributes to security is structured error handling with exceptions. Because of its support for exceptions, the JVM has something structured to do when a security violation occurs. Instead of crashing, the JVM can throw an exception or an error, which may result in the death of the offending thread but shouldn't crash the system.

Throwing an error (as opposed to throwing an exception) almost always results in the death of the thread in which the error was thrown. This is usually a major inconvenience to a running Java program, but won't necessarily result in termination of the entire program. If the program has other threads doing useful things, those threads may be able to carry on without their recently departed colleague. Throwing an exception, on the other hand, may result in the death of the thread, but is often just used as a way to transfer control from the point in the program where the exception condition arose to the point in the program where the exception condition is handled.

Structured error handling contributes to Java's security model by helping to improve the robustness of Java programs. The Java compiler forces programmers to deal with exceptions that methods declare they may throw. This encourages programmers to write code that actually handles exception conditions that may reasonably be expected to arise as their programs run. If a program encounters a catastrophic error condition, the structure error handling mechanism enables the program to avoid an uncontrolled crash and make a more graceful exit.


The sandbox security model is an intrinsic part of Java's architecture. The sandbox, a shell that surrounds a running Java program, protects the host system from malicious code. This security model helps give users confidence in downloading untrusted code across network.

The sandbox is designed into the Java virtual machine and Java API. It touches all corners of the architecture, but can be divided into four main components:

  • Safety features (covered in this article)
  • Class loaders (this will be covered next month)
  • Class verification (this will covered in the October issue)
  • The security manager (this will be covered in the November issue)

Learn more about this topic

1 2 Page 2
Page 2 of 2