BUY IT!
Securing Java

Previous Page
Previous Page
Beyond the Sandbox: Signed Code and Java 2
CHAPTER SECTIONS: 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8

Section 5 -- An Introduction to Java 2 Security

Next Page
Next Page

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]:

Fine-grained access control: The ability to specify that code with proper permissions is allowed to step outside the sandbox constraints gradually (for example, an applet signed by a trusted key might be allowed to open arbitrary network connections).

Configurable security policy: The ability for application builders and Java users to configure and manage complex security policies.

Extensible access control structure: The ability to allow typed permissions and to group such permissions in logical, policy-oriented constructs.

Security checks for all Java programs: A departure from the concept that built-in code should be completely trusted. (It is this capability that serves to erase the once-important distinction between applets and applications.)

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.


A View from 50,000 Feet

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.

Fig 3.4

Figure 3.4 Mobile code in Java 2 interacts with user defined policy through the AccessController.

Byte code may make calls to potentially-dangerous functionality. When such calls are made, the AccessController (new to Java 2) consults policy and uses stack inspection to decide whether to allow or disallow a call. Decisions are based on the identity of the code.

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.


A Simple Example
An easy example of how this works in practice is helpful. First, imagine a policy representing the statement "code from "www.rstcorp.com/" applet signed by 'self' is given permission to read and write files in the directory /applet/tmp and connect to any host in the rstcorp.com domain." Next, a class that is signed by "self" and that originates from "www.rstcorp.com/" applet arrives. As the code runs, access control decisions are made based on the permissions defined in the policy. The permissions are stored in permission objects tracked by the Java runtime system. Technically, access control decisions are made with reference to the runtime call stack associated with a thread of computation (more on this later).

Previous Page
Previous Page


Search Help
Next Page
Next Page


Menu Map -- Text links below

Chapter... Preface -- 1 -- 2 -- 3 -- 4 -- 5 -- 6 -- 7 -- 8 -- 9 -- A -- B -- C -- Refs
Front -- Contents -- Help

Copyright ©1999 Gary McGraw and Edward Felten.
All rights reserved.
Published by John Wiley & Sons, Inc.