Securing Java

Previous Page
Previous Page
The Base Java Security Model: The Original Applet Sandbox
CHAPTER SECTIONS: 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 10 / 11 / 12 / 13

Section 4 -- The Java Language and Security

Next Page
Next Page

Many of the features of Java as a language (as introduced in Chapter 1) have important security implications. This is important for everyone: for developers charged with creating secure code; for users who must in the end rely on developers' products; for system administrators who install, configure, and manage the products; and for managers who decide which products are developed and how they are deployed. It is a well-known fact in computer security that security problems are very often a direct result of software bugs. That leads security researchers, including the authors, to pay lots of attention to software engineering. The hope is to avoid the ever-present penetrate-and-patch approach to security by developing more secure code in the first place. Although Java is no silver bullet, it can certainly help.

Object-orientation and a modern memory model both turn out to have a positive impact on Java security. The notions of data hiding, abstraction, and encapsulation, in particular, can help encourage better design for security. In Java, objects cannot be directly manipulated by a programmer; instead, they can only be accessed through their public interfaces. This is a good thing. Programmers cannot directly access memory either, but must use object references. This fact makes it much harder for a nasty program to trawl through memory looking for interesting data such as passwords and credit card numbers.

All of these features also help to make Java programs a bit more robust (on average) than programs written in other popular languages. After all, mechanisms that prevent programs from deliberately accessing memory that should be off-limits will also prevent buggy programs from accidentally accessing the wrong memory. Since most security flaws exist because of programming bugs, anything that reduces the general level of bugginess in software is good for security. Java helps conscientious programmers reduce the odds that their code contains security bugs.

Every object and primitive data element in Java has a built-in access level associated with it, either the explicit private, protected, or public access level, or a default access level.

  • Private variables and classes can only be accessed by the class that created them.
  • Protected variables and classes can only be accessed by the class that created them, the creator's subclasses, and classes in the same Java package.
  • Public variables and classes are accessible by all classes.
  • By default, entities in a class can be accessed by code within the class that defines them, or by a class in the same package as the class that defines them.
The access levels should be mostly familiar to C++ developers, although the Java definitions differ slightly. (Access levels star in one of Java's security holes, as we will see in Chapter 5.)

There is an essential difference between languages like C++ and Java that stems directly from Java's requirement that objects can only be manipulated through standard interfaces. In C++, a programmer could declare certain variables inside an object private, but then access these variables in sneaky ways. Though the C++ compiler may stop obvious front-door operations (for example, not allowing an arbitrary class to access private elements of another), the back door is wide open. Using pointer arithmetic, casting, and other such means, a C++ programmer can scan through a program's allocated memory (and in fact, manipulate memory) at will. Why anyone would deliberately do such a thing inside his or her own code is an interesting question (although it might be done accidentally), but this sort of thing matters in Java where distinct applets that don't trust each other may share the same VM. The access levels described here help address this concern. Also helping to safeguard memory in Java are the following:

  • Objects and methods declared final cannot be changed or overridden (ignoring this rule would seriously break the Security Manager, among other things).
  • Array bounds are checked for all array accesses (putting to rest a very common mistake that plagues C).
  • Object casting is restricted (necessary to ensure type safety).
  • Variables cannot be used before they are initialized (another memory-protection mechanism).
  • Garbage collection automatically frees memory when it is no longer needed.
Type safety is certainly a key language feature in Java. It is important enough to Java security that it deserves its own section (see page 74). For now, suffice it to say that making sure the VM does not become confused about the kinds of objects it is using is essential. This is pretty obvious if you think about the fact that the security model itself is a collection of classes with certain types.

In this section, we have covered a nice set of features of Java that can help make it easier to write secure code (and help you rest easier if you use such code). However, how are these rules enforced? That is up to the Java sandbox.

Previous Page
Previous Page

The Web

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.