Signatures alone don't provide the infrastructure needed to allow Java code out of the sandbox gradually. Access control mechanisms are required as well. In JDK 1.1, for example, applet code signed by a trusted party can be treated as trusted local code, but not as partially trusted code (without an inordinate amount of extra programming). There is no notion of access control beyond the one-and-only trust decision made per class. That means in practice, JDK 1.1 offers a black-and-white trust model much like ActiveX (although with the clear advantage that untrusted code must stay in the sandbox).
The new security architecture in Java 2 has four central capabilities [Gong and Schemers, 1998]:
It is important to note that the first three of these four capabilities are not really new to Java. Java is a powerful programming language, and it has always been possible to implement complex, configurable, extensible security policies based on fine-grained access control. It was just exceptionally tricky. Java 2 serves to make this task possible for mere mortals.
At its heart, the Java 2 security model has a simple idea: Make all code run under a security policy that grants different amounts of privilege to different programs. While the idea may be simple, in practice, creating a coherent policy is quite difficult. Figure 3.4 shows the role that mobile code identity and policy play in Java 2.
Java 2 code running on the new Java VMs can be granted special permissions and have its access checked against policy as it runs. The cornerstone of the system is policy (something that will not surprise security practitioners in the least). Policy can be set by the user (usually a bad idea) or by the system administrator, and is represented in the class java.security.Policy. Herein rests the Achilles' Heel of Java 2 security. Setting up a coherent policy at a fine-grained level takes experience and security expertise. Today's harried system administrators are not likely to enjoy this added responsibility. On the other hand, if policy management is left up to users, mistakes are bound to be made. Users have a tendency to prefer "cool" to "secure." (Recall the dancing pigs of Chapter 1.)
Executable code is categorized based on its URL of origin and the private keys used to sign the code. The security policy maps a set of access permissions to code characterized by particular origin/signature information. Protection domains can be created on demand and are tied to code with particular CodeBase and SignedBy properties. If this paragraph confuses you, imagine trying to create and manage a coherent mobile code security policy!
Code can be signed with multiple keys and can potentially match multiple policy entries. In this case, permissions are granted in an additive fashion.
Copyright ©1999 Gary McGraw and Edward Felten.