Mobile Code and Security: Why Java Security Is Important
Java security is more important than ever. Since its introduction in 1995, Java has become one of the most popular development platforms on the planet. In fact, Java has been widely adopted more quickly than any other computer language. It now easily tops the list of preferred platforms for Internet-savvy mobile code. There are tens of thousands of Java developers (some say hundreds of thousands), and demand for Java skills appears to be growing. Java is definitely here to stay.
Java holds great promise as a platform for component-based software, embedded systems, and smart cards. This means Java is poised to play an important enabling role in e-commerce as these systems move from ether-ware to reality. Java components (aka JavaBeans) are appearing at a rapid pace, and encapsulate critical functionality for transaction-based systems. Java smart cards for e-commerce will debut soon.
But what of the hue and cry over security? Should people be so concerned about the security implications of Java that they disable Java in their browsers? Should developers avoid using Java in their systems in favor of other languages like C++? Should system administrators block Java content at the firewall (or better yet, can they)? Should business people avoid Java because of security problems? These are the some of the questions this book answers. The answers are nontrivial, and the issues are as complex as they are important.
Java security is important to a number of distinct sets of people:
Web users, including one of the authors’ 88-year-old grandmother, need to understand the risks of using a Java-enabled browser.
Developers of Java code that lives and works on the Internet need to keep security in mind when they are writing programs.
System administrators need to think carefully about how mobile code, including Java, impacts the security of the systems they run.
Business people need to understand what Java security risks are so they can make informed business decisions based on fact and not fiction.
As you can see, Java security issues are multifaceted. This book has useful information for all four groups, whose interests overlap in many ways.
Java security is a hot topic, but that does not make it an easy one. By itself, computer security is not well-understood. Throw Java into the mix and things become even murkier. There is much confusion and misinformation floating around about Java and security. Beware of snake oil, impossible claims, and consultants who pretend to have all the answers. Also be aware that major vendors are just as capable of misinformation as fly-by-night companies. Skepticism, Rene Descartes’ 300-year-old philosophical insight, is strangely relevant to computer security at the turn of the millennium. In fact, skepticism turns out to be an excellent strategy. Ask hard questions; you might be surprised by the answers.
The most pressing security concerns surrounding Java impact millions of people¾ that is, anyone who browses the Web. Given that there are tens of millions of Netscape Navigator and Microsoft Internet Explorer users, the client security issue is no minor detail.1 It turns out that a majority of the users of these browsers are also Java users, whether they know it or not. Java is built in to Netscape Navigator and Internet Explorer, so if you use either of these products, you are a Java user.
Just as all Internet users are taking security risks, all Java users are taking security risks. Because of the way Java works, computer security issues are a fundamental concern. Most Java code is automatically downloaded across the network and runs on your machine. This makes it very important to limit the sorts of things that Web-based Java programs can do. Simply put, a hostile Java program could trash your machine. Because Java is inherently Web-based, it provides crackers with an easy way to implement a Trojan Horse—a program that may seem innocent enough on the surface, but is actually filled with well-armed Greeks. Also of concern is the problem of computer virus propagation. Fortunately, the creators of Java have made a good effort to protect users from these hazards. For example, writing a Web-based Java virus as an applet would be very hard. (Writing a Microsoft Word macro virus like the concept virus is, by contrast, easy.) Because mobile code security is new, difficult, and complicated, Java’s masters have not always been successful at protecting everyone all the time.
One goal of this book is to educate Java users about the risks that they incur by surfing the World Wide Web with Java-enabled browsers. This chapter provides a gentle introduction to Java, and explains why Java is potentially dangerous.
Java security is essential to developers as well. As a platform, Java has much to offer in terms of security:
• Java has advanced cryptography Application Program Interfaces (APIs) and class libraries.
• Java includes language-level security mechanisms that can help make developing secure code easier.
• There are aspects of Java that make it more difficult to write insecure (unsafe) code.
This book explains how to use the security features built in to the Java environment inside your own programs.
That’s not to say that developing secure programs with Java is trivial or automatic. Anyone who reads the newspapers or the trade press can see how often skilled programmers write code with security bugs. You can make almost as many gaffes developing security-critical code in Java as in any other language. Because of Java’s security APIs and its position as a leading e-commerce platform, it is likely that Java will be used to carry out some very important activities. That means developers need to learn as much as they can about Java security. Know your enemy. Think about what might confront your code in terms of malicious attacks. Mitigate risks by designing, coding, and testing carefully.
A second goal of this book is to teach Java developers and project managers about the sorts of things that will confront their code in "the wild." If you’re a seasoned Java developer (something that it was impossible to be a mere handful of years ago), this book will show you in great detail how the security model works. There are lessons to be learned from the Java attacks we cover. After all, like you, Java’s designers and developers were serious about what they were doing, but as we have seen, even the most subtle bug can be turned into a security disaster.
System Administration and Java
Today’s system administrator is seriously overworked, and security is a big part of the problem. The days of the isolated Local Area Network (LAN) are behind us. Now, most networks are connected directly to the Internet, which means security is more important than ever. Some early adopters and sites with a lot to lose try to protect themselves with advanced security mechanisms such as firewalls, secure shells, and virtual private networks. Many sites, however, have a long way to go before they are "secure enough" (whatever that means). Mobile code systems, including Java, make administering site security trickier.
The problem is that users want Java content, but system administrators don’t want to take on unnecessary risks. This is a classic example of the well-known tradeoff in computer security between functionality and security. Computer security boils down to managing risks, which in turn implies that the way to make better-informed decisions is to get a handle on the risks.
A third goal of this book is to present an informed discussion of the real risks of mobile code. Burying your head in the sand like an ostrich is not a good solution, because security problems are unlikely to miraculously disappear. However, the risks do not necessarily warrant throwing the Java baby out with the bath water. Such a move may leave your users high and dry.
Even if the risks turn out to be too much to bear (a decision that is very much context dependent), system administrators need to be wary of snake-oil "solutions" to the mobile code problem. There are a number of products on the market that purport to improve Java security. The question is, do they work? We will delve into these issues as well.
Java Gets Down to Business
Making informed business decisions at the edge of the technology curve has never been an easy task. In addition to the technological concerns discussed earlier, there are often intangible factors to consider. What impact will perceived security risks (whether justifiable or imagined) have on potential customers? Is Java the best platform to use when designing e-commerce systems? How will the use of Java within an enterprise affect security risks? What are the security challenges in designing and deploying database-backed Web servers and three-tier applications?
It is surprising that some of the same companies that disallow the use of Java (often for silly reasons) expect their customers and business partners not to disallow Java. The information in this book can help business managers and leaders make better decisions about Java security. Good data are essential to decision-making, but sometimes good data are hard to find.
The Java programming environment from Sun Microsystems is designed for developing programs that run on many different kinds of networked computers. Because of its multiplatform capabilities, Java shows great promise for relieving many of the headaches that developers encounter when they are forced to migrate code between different types of operating systems. Code that is written in Java should run on all of the most popular platforms—everything ranging from Macintosh and Windows/Intel machines to Linux and Solaris boxes.
Recently, the cross-platform capabilities of Java have been called into question. This has led Sun’s marketing phrase, "write once, run anywhere" to be reinterpreted by skeptics as "write once, test everywhere." Part of the problem is that not all implementations of Java are completely interoperable with Sun’s version. Disagreement over what constitutes Java has generated at least one high-profile lawsuit. Most people, including a majority of Java developers, would like to see Java become a standard so that what happened to C (which was itself supposed to be a cross-platform language) doesn’t happen to Java.
In any case, a nice side effect of Java’s built-in portability is that one special kind of Java program (popularly known as an applet ) can be attached to a Web page. More technically speaking, applets are embedded into a Web page’s hypertext markup language (HTML) definition and executed by Java-savvy browsers.2 Such Java-enabled browsers automatically download and begin running any Java applet they find embedded in a Web page. Java code’s ability to run on many diverse platforms makes such "magic" possible.
The ability to dynamically download and run Java code over the Net has led some computer pundits to proclaim that the age of truly component-based software development may actually have arrived. The idea is that instead of buying huge monolithic word processing behemoths with hundreds of obscure features that most users will never need, users can instead "create" a personal word processor on the fly out of Java building blocks. This modern sort of programming is akin to building a large toy ship out of Lego blocks.. Or, more realistically, the process of creating a component-based software product could be likened to building a highway bridge out of standardized structural components.
Sun is advocating a Java component architecture called JavaBeans. There are a number of companies creating sets of JavaBeans for various purposes. If these efforts are successful, developers will be able to create programs by putting together sets of prefabricated Beans as illustrated in Figure 1.1. Microsoft’s Component Object Model (COM) is very much oriented this way, although it is not specifically designed to use Java. Component-based software has its own interesting security implications and open questions. For example, how can the developer of a system trust a component manufacturer not to have (purposefully or accidentally) introduced security holes into the system? How can a component manufacturer anticipate all uses to which a component will be put? And so on. These sorts of questions are the topic of current research, including some by the authors of this book.
Figure 1.1 Component-based software allows a designer to create large applications from standardized building-blocks.
Components in Java are known as JavaBeans. The idea of using pre-fabricated components to build large-scale applications will likely do for software what the Industrial Revolution did for manufacturing.
Thinking even farther into the future, one can imagine a fundamentally new kind of computer document that contains the word processing, spreadsheet, and database software that was used to create it. Using a document’s embedded components, a writer or editor could modify the document on any platform. The built-in components would allow different people using different machines to edit the document without worrying about the kind of computer they are using or file type compatibility issues. If Java is developed to its full potential, this future world may not be far off.
The new idea behind all of these exciting aspects of Java is simple: the ability to send data that can be automatically executed wherever it arrives, anywhere on the Net. Java is an implementation of executable content, or mobile code. This powerful idea opens up many new possibilities on the World Wide Web. For the first time it is possible to have users download from the Web and locally run a program written in a truly common programming language.
These features of Java are certainly exciting; however, Java’s fantastic potential is mitigated by serious security concerns. Security is always an issue when computers are networked. Realistically speaking, no computer system is 100-percent secure. Users of networked computers must weigh the benefits of being connected to the world against the risks that they incur simply by connecting. In practice, the goal of a security policy is to make such tradeoffs wisely.
One of the key selling points of Java is its use as a "cross-platform" language for creating executable content in the highly interconnected world of the Internet. Simply by using a Web browser, a Web surfer can take advantage of Java’s cross-platform capability. Of course, the activity of locally running code created and compiled somewhere else has important security implications. These implications are one focus of this book.
The same risks and benefits that apply to connecting to the Internet itself directly apply to using the Java language. As you will see, these concerns become particularly critical when "surfing the Web." The same technology that allows Java applets to enliven once-static Web pages also allows unscrupulous applet designers to invade an unsuspecting Java user’s machine. With Java applets showing up everywhere, and many millions of people using Java-enabled browsers, it pays to know where you are pointing your browser.
The Power of Networking
Networking has changed the face of computing. We once thought of computers as calculating machines, but now most people rightly view them primarily as communication tools. An Internet connection is as essential a part of today’s computer as a disk drive. The move toward a globally networked world has been significantly furthered by Java.
The Internet: A World of Connections
Since its birth in the early 1970s as a 12-node network called the ARPANET,3 the Internet has exponentially exploded into a worldwide network that provides a central piece of the planet’s information infrastructure. Figure 1.2 shows the growth pattern of the Internet from its humble 12-host beginning through today’s some 30-million registered addresses.
Figure 1.2 Growth of the Internet since its early days as the ARPANET.
Data from Network Wizards (www.nw.com). The Internet continues to grow at an astounding rate.
Connecting computers together in a network allows computer users to share data, programs, and each others’ computational resources. Once a computer is put on a network, it is possible to access a remote machine in order to retrieve data, or to use its CPU cycles and other resources. Along with this ability comes concern about security. Computer security specialists worry about issues such as:
• Who is allowed to connect to a particular machine
• How to determine whether or not access credentials are being faked
• Who can access which resources on a shared machine
• How to protect data (especially in transit) using encryption
• How and where to collect and store audit trails
Whenever machines are networked, these concerns must be addressed.
The Internet, being the world’s largest network of machines, has encouraged research into these security issues. Mechanisms now in place go beyond simple password authentication, to firewalls and security checking tools such as SATAN, ISS, and Ballista. New ideas in computer security are constantly becoming available on the Net. Security approaches currently in preliminary use include encryption-based authentication, encrypted communications, and intrusion detection based on Artificial Intelligence (AI) [Hughes, 1995; Garfinkel and Spafford, 1996; Ghosh, 1998]. Computer security has recently matured into a substantial commercial enterprise as well. As in any new field, however, there is as much hype as there are barrels of snake oil. If it sounds too good to be true, it probably is. Buyer beware.
The Web: Making the Internet Enticing
One of the driving forces behind the exponential growth of the Internet in the last several years has been the introduction of the World Wide Web. In 1992, Tim Berners-Lee, a British researcher at the CERN physics facility in Europe, invented the Web, a new way to use the Internet. His invention introduced hypertext markup language (HTML) and Web browsing to the world. In 1993, Marc Andreessen helped to write the Mosaic Web browser while affiliated with the National Center for Supercomputer Applications (NCSA). He later cofounded the company now known as Netscape Communications. Though it may be hard to believe, the Web is only a few years old.
Before the invention of the Web, the Internet was almost exclusively text based. Researchers used it to transfer files to one another, and to keep in touch via email. After the Web was invented, it suddenly became possible to see graphical pages sent across the Net by Web servers. These Web pages can include pictures, sound, video, and text, as well as hyperlinks to related pages. A Web browser provides an easy-to-use, intuitive interface for "surfing," or traveling around the Web, visiting other people’s pages. Figure 1.3 shows how a typical Web page looks when viewed with the Netscape browser. Note that the page includes a Java applet.
Figure 1.3 A view of this bookís companion Web site (www.rstcorp.com/java-security.html) as displayed by Netscape Communicator.
Current Web browsers all include the capability of running mobile code automatically.
Ease of use is partially responsible for the astonishing numbers of Web users, and perhaps for the sense of safety that most Web users seem to enjoy. In addition, creating Web pages is a relatively simple process. HTML editors like Netscape Navigator Gold and Microsoft FrontPage make the job especially easy. Given one of these editors and a Web server, you have all the pieces you need to create your own Web site. An alternative to using an HTML editor is to write HTML code directly. Either way, this snazzy HTML facade makes the Internet more attractive than ever.
As shown in Figure 1.4, the Web has grown just as quickly as the Internet itself. The figure charts a conservative estimate of the number of Web servers on the Net. It is these servers that allow people to make Web pages available to everyone. The figure does not properly reflect the number of Web pages that are out there, which some people number in the tens of millions. Keep in mind that a server has the potential to serve hundreds or even thousands of pages for multiple users simultaneously.
Figure 1.4 Growth of the World Wide Web since its introduction in 1993.
Data from the Internet Society (www.isoc.org).
Java: Spicing Up the Web
HTML-based Web pages are certainly a big step up from using the obscure, text-basedUnix incantations of ftp, news, gopher, wais, and telnet to get around on the Net; however, they also have a major drawback. Much like the page that you are reading now, Web pages are static. Wouldn’t it be better to have interactive Web pages that dynamically change themselves according to feedback from a user? Wouldn’t it be better to program your Web pages to accept input, compute results, and then display them?
This sort of dynamic activity should ring a bell. After all, programming languages allow people to program machines to do just these sorts of things. Why not make a programming language for the Web?
That is the essence of Java. Java is a full-featured programming language that allows programmers to compose executable content for the Web. The Java language is designed to be usable on all platforms so that code can move from one machine to another and still work, regardless of the kind of machine it ends up on. Cross-platform compatibility has always been a stumbling block in previous attempts to create programming languages for executable content. Mobile code can only truly be mobile if it can be executed on all platforms without porting and recompiling!
In order to allow Java to run on a computer, the administrator must first install a Java Virtual Machine (JVM), or a browser that includes a Java VM. The JVM interprets Java instructions and translates them into machine-specific instructions. This allows Java to be run on many different types of machines.4 For old timers, the whole idea is reminiscent of P-code from the 1970s.
Having a well-defined, platform-independent definition allows Java to get around problems that have plagued the C programming language, making C less platform independent than its designers intended. Unlike C programs, Java programs are not hampered by machine-dependent structures such as:
• Byte ordering (low or high endian)
• Pointer size (16 or 32 bit)
• Integer size (16 bit, 32 bit, or 64 bit)
Java’s careful definition shields it from these platform-specific elements of programming. Each Java VM is written to a specific platform, and translates the more generic Java instructions into platform-specific instructions.
Java has upped the ante on the Web. The best Web pages now include Java applets that do everything from displaying selectable news tickers to providing frontend graphical user interfaces (GUIs) for internal databases. There are even some Web-based videogames written in Java. Java applets have become commonplace.
The Promise of Java
Downloading Code: Not a New Problem
In the early days of the Internet, everyone agreed that downloading arbitrary binaries and executing them on your machine was a bad idea. Of course, most people did it anyway. By the mid 1980s, there was lots of freeware and shareware out there to be downloaded. To find it, you could usearchie, which provided a way to search a large index of anonymous ftp content. Once you dug up some leads (often several ASCII pages worth), you chose your target and ftp'ed what you needed. Then you installed and ran it.
The risks of running some random person's downloaded-from-the-Net code on your machine are clear. If the code has a virus attached, your machine can be infected. If the program is a Trojan Horse that appears to be doing something useful while it is actually doing something nefarious, your machine can become "owned" by someone else. This is especially dangerous for machines connected to the Net. How can we be sure that a program that someone says is useful hasn't been hijacked to do something nasty?
When it works flawlessly, the Java security model provides one possible answer to this question, as it was designed to allow untrusted programs to be run on a computer safely. As we will see, the base Java security model is meant to counter the threat of viruses and other forms of attacks. But in the early days of the Net, Java did not yet exist. (To be completely accurate, Java was evolving in the early 1990s from an embedded platform called Oak that was meant to be used for smart devices like that Internet-enabled toaster you’ve heard so much about.)
Back to our history . . . The question in the late 1980s was, "how could a user be sure that a program had not been hijacked (or Trojan’ed)? Checksumming provided part of the answer. A checksum is a simple computation performed on a piece of code to provide a digest, or "thumbprint," of a program. (Combine this with digital signatures and you have a system that can provide both data integrity and authentication, which is most desirable, as we will discover in Chapter 3, "Beyond the Sandbox: Signed Code and JAVA 2."JAVA 2
Not many people were into checksums back then, but they existed for at least a few anonymously downloadable programs. Of course, who was to say that a program's checksum hadn't been tampered with? In reality, most people either ignored the risks or chose to live with them.
Skipping the advent ofgopher, which most people pretty much ignored anyway, the next big thing was the Web. As discussed in the last section, the Web got its start in 1992. At first, the Web was static. Java changed all that, making it possible for a Web server to provide programs as content. Java applets are these programs. The dangers of mobile code and systems for addressing these dangers are the focus of this book. But there’s still a drawback, even with the power that Java adds to the Web¾ the only way to tell when new content has been added to a Web page is to surf back over and find out. That’s where push technology comes in.
Push: Too Much of a Good Thing?
As if surfing the Web with a Java-enabled browser isn’t bad enough security-wise, another new step in mobile code delivery appears to be "push" technology. Push provides a way to have information (including mobile code) automatically flow to your machine¾ without you even asking for it! (Well, you do have to set things up once in the beginning, but after that, no more clicking.) Now the inconvenience of clicking on a hyperlink is completely removed. Heck, you don't need to make any decisions at all. Just sit back and watch the content (which may include Java applets, ActiveX controls, and client-side scripts) come to you. With push it is possible to subscribe to "channels" that do things like provide constant stock information, news headlines, and (most dangerously of all) software updates.
There are many push systems out there. Two of the most popular are Castanet by startup Marimba, and PointCast by PointCast, Inc. The security systems of Castanet and PointCast are briefly covered in an article written by McGraw entitled "Don’t Push Me: The Security Implications of Push," which is available at
Push channels are now available in both Internet Explorer 4.0 and Netscape Communicator.
First off, push is not very well named. It should actually be called "timed pull." Most systems, including PointCast, work by having a tuner program, which functions like a fancy browser, issue HTTP requests for information from a push server. (This is the "pull" part.) Once requested, the information comes back across the Internet as HTML-based HTTP traffic and is eventually displayed in a special window. PointCast is set up to take over the screen when the computer is not in use, much like a screensaver program. Every once in a while, the program will wake up and check for new information, which is grabbed in chunks and sometimes cached. (This is the "timed" part.)
Let’s get this straight: It is still a really bad idea to download and run arbitrary binaries off the Internet. Automating things so that this happens more easily, behind the scenes, doesn't serve to make it any less dangerous. We've gone from having to request binaries through the text-based ftp interface and install them, through clicking on a hyperlink (the Java model), all the way to having content come to you.
In the meantime, security issues have yet to be properly addressed. How do you know that the information a push server is sending you is secure? How do you know that the update that was just pushed onto your PC is really from the company that developed the software? These questions are familiar ones to people interested in security. What we need to make push systems safe is strong authentication, foolproof data integrity, and trust in the broadcasters. Current push systems are only beginning to address security concerns.
Java in a Demitasse
The security concerns raised in this book apply equally to both Java users and Java developers. Using Java is as easy as surfing the Web. The simple use of Netscape Navigator, Internet Explorer, or any other Java-enabled browser to run Java applets is a risky activity. In order to really understand these risks, it is important to gain a deeper understanding of how Java really works. Here is a short but thorough introduction to the Java language.
The Java development environment comprises three major components:
1. A programming language that compiles into an intermediate, architecturally neutral format called byte code
2. The Java Virtual Machine that executes the byte code
3. An execution environment that runs on the JVM and provides some base classes useful for building complete applications
Figure 1.5 shows how these three parts of the Java environment work together to provide executable content for the Web. The Java Developers’ Kit (JDK) is provided free to all. It includes the three parts of the Java environment outlined here. To get your own copy, point your browser to URLjava.sun.com
Figure 1.5 How Java implements the original sandbox approach to mobile code.
Java source code is compiled into Java byte code which is transferred across the Web to the browser that requested it. The HTML in a Web page specifies which code is to be fetched from the Web server. The requesting Web browser, prompted into action when a user clicks on a hyperlink, (1) fetches the code from the Web, (2) Verifies it, (3) instantiates it as a class or set of classes in a namespace. The applet executes and (4) invokes a dangerous method (5) causing the Security Manager to be consulted before the method runs. The Security Manager (6) performs runtime checks base on the calling class’s origin and may veto some activities.
Because Java byte code runs on the Java Virtual Machine, it is possible to run Java code on any platform to which the JVM has been ported. Some Web browsers, such as Netscape and Internet Explorer, include an encapsulated version of the JVM. Using their built-in VMs, such Java-ready browsers can automatically download and execute Java applets when a user accesses an HTML Web page with the<APPLET> tag.
The Java Language
One of the first public introductions to Java came in the form of a whitepaper released by Sun (and since updated many times) [Sun Microsystems, 1995]. An especially pithy sentence from that document attempts to describe the fundamental aspects of Java all at once. It reads:
Java: A simple, object-oriented, distributed, interpreted, robust, secure, architecture neutral, portable, high-performance, multi-threaded, and dynamic language.
Quite a collection of buzzwords. In fact, some people joke that Java is "buzzword compliant." This book is concerned mostly with the security claim, of course, but in order to understand the implications of Java for computer security, you need to grasp the other important characteristics of the language first.
As the quote claims, Java has many interesting features. They will be briefly introduced here. The Java language is:
Object-oriented: Unlike C++ which is an objectivized version of C, Java is intrinsically object-oriented. This changes the focus of programming from the old procedural way of thinking (as in C and Pascal) to a new data-centric model. In this new model, data objects possess associated methods. Methods perform actions on data objects. Every Java program is composed of one or more classes. Classes are collections of data objects and the methods that manipulate these data objects. Each class is one kind of object. Classes are arranged in a hierarchy such that a subclass inherits behavior and structure from its superclass. Object-oriented languages were designed using the physical world as a metaphor. Classes communicate with each other in much the same way that real physical objects in the world interact.
Strongly typed: This means that a Java program cannot arbitrarily access the host computer’s memory. Memory access by Java programs is limited to specific, controlled areas having particular representations. Type safety is verified when code is loaded into the JVM by the Byte Code Verifier (see Chapter 2 of this book, "The Base Java Security Model: The Original Applet Sandbox"). In addition, runtime checks on type safety (such as checks for array bound overflow, type incompatibility, and local-versus-remote code security policy) are all handled by the Java Virtual Machine. As we shall see, type safety is essential for Java security. In fact, a majority of serious Java security attacks target the type system.
Multi-threaded: Java programs can execute more than one task at the same time. For example, a multimedia Java applet may want to play a sound file, display a picture, and download a file all at once. Since Java is multi-threaded, it supports the concurrent execution of many lightweight processes. An obvious benefit of this capability is that it improves the performance of multimedia applications at the user end. Java’s built-in support for threads makes designing such applications far easier than it is in C and C++. Primitives for synchronization are also provided in Java.
Java has other important characteristics adapted from modern programming languages such as Scheme (a popular dialect of Lisp) and ML. In particular, Java uses:
Garbage collection: Memory management is usually handled in one of two ways. The old-fashioned approach is to have a program allocate and de-allocate memory itself. This approach allows all sorts of insidious errors and hard-to-squash bugs. C, for instance, uses this method. By contrast, Lisp introduced the modern concept of garbage collection in 1959! Garbage collection requires the system (rather than the programmer) to keep track of memory usage, providing a way to reference objects. When items are no longer needed, the memory where they live is automatically freed so it is available for other uses. Java provides a garbage collector that uses a low-priority thread to run silently in the background. Java’s memory management approach has important implications for the security model since it prevents problems associated with dangling pointers.
No pointers: This is also a feature of Java’s modern memory management scheme. Instead of allowing access to memory through pointers, memory is managed by reference. The crucial difference between references and pointers is that references cannot be manipulated through arithmetical means (as can pointers). This eliminates many potential bugs. Pointers are one of the most bug-prone aspects of C and C++. Eliminating pointers has the effect of making Java a much more reliable and safer language.
Exception handling: This defines how the program will manage an error condition. For example, if a Java program tries to open a file that it has no privilege to read, an exception will be thrown. Exception throwing and catching is a system for gracefully managing runtime errors which might otherwise crash a system. This is a good idea if you are concerned about security.
Dynamic linking: Software modules (classes in Java) are linked together as they are needed. The Java language knows where it should look for classes that need to be linked while a Java program runs. By contrast, C has a linking phase during which all needed constructs are linked before the program is run. The linking phase in C is static since library functions are assembled together with other code into a complete executable at compile time. Dynamic linking makes it easier to keep Java programs up-to-date since the latest version of a class will always be used. This can turn out to be a problem for programs that expect a class to behave the way it has in the past, and are surprised when a new version appears. Version control and software assurance become much more complicated with dynamic linking too. Java finds classes that it needs by searching for them in locations specified in the classpath environment variable (though the system is undergoing revision for JAVA 2). (As we will discuss in Chapter 2 of this book, it turns out to be very hard to ensure type safety when dynamic class loading is allowed.)
Though it has more than doubled in size since its original introduction, Java is still a relatively simple language. This is especially apparent when Java is compared with C and C++ [Daconta, 1996]. In C, there are often many possible ways in which to do the same thing. Java tries to provide only one language mechanism with which to perform a particular task. Also, Java provides no macro support. Although some programmers like using macros, macros often end up making programs much harder to read and debug.
The designers of Java made their language simple by removing a number of features that can be found in C and C++. Things that were removed include thegoto statement, the use of header files, the struct and union constructs, operator overloading, and multiple inheritance. Together with the elimination of pointers, removal of these aspects of C and C++ makes Java easier to use. This should result in more reliable code.7
We will revisit the impact that Java’s features as a language have on security in Chapter 2.
Portable Byte Code and the Java Virtual Machine
The second major component of the Java development environment is the Java Virtual Machine. The VM makes Java’s cross-platform capabilities possible. In order to run Java byte code on a new platform, all that is required is a working VM. Once the VM has been ported to a platform, all Java byte code should run properly.
Making a byte code/VM pair that works well on many varied platforms involves setting a few things in stone. Java has variables that are of fixed size and of fixed format. Aninteger in Java is always 32 bits, no matter what the word size of the machine running Java. Making data formats machine independent and compiler independent is crucial to making Java truly portable. The very different way in which variables are managed on different C platforms causes no end of portability problems for C programmers.
The VM also makes use of symbolic data stored inside of Java byte code files. Java byte code contains enough symbolic information to allow some analysis of the byte code before it is run. This is one way the Java environment ensures that Java’s language rules have been followed by the compiler—something critical to security. Rules checked include, for example, type safety rules, and ensuring that certain things claiming to be of a certain type actually are of that type. Since the Java byte code Verifier is a critical part of the security model, it is discussed in detail in Chapter 2.
Using a Virtual Machine has obvious important repercussions for the Java approach. The VM makes portability possible, and it helps to ensure some of Java’s security features. Since Java is often implemented using an interpreter, speed can be an issue. Interpreted languages are inherently slow because each command must be translated to native machine code before it can be run. With a compiler, this work is all done ahead of time, when an executable is created for some particular platform. Without just-in-time (JIT) and hotspot compilers, Java’s interpreted code is about 20 times slower than native C code. When this new technology is used, Java speeds begin to approach native C.
Reusable Class Modules
The third part of the Java development environment is a set of predefined classes that implement basic functionality. The "personal" version of the JDK includes, for example, an Abstract Windowing Toolkit (AWT). These classes provide a set of graphical user interface (GUI) tools for creating windows, dialogue boxes, scrollbars, buttons, and so forth. Java also includes classes for full network support that provide application program interfaces (APIs) for sockets, streams, URLs, and datagrams. A POSIX-like I/O system with APIs for files, streams, and pipes makes the environment comfortable for experienced Unix programmers. Classes are grouped together into packages according to their functionality. Table 1.1 lists the packages included in the Java Developers’ Kit (JDK) version 1.1. Note that Java’s core classes have grown significantly in the last few years.
Table 1.1 Packages Supplied by the JDK (version 1.1) Provide Multiplatform Primitives from Which Complete Applications Can Be Assembled.
Java In A Nutshell[Flanagan] is an excellent reference describing these packages
java.applet The Applet class.
java.awt Abstract Windowing Toolkit: The AWT provides graphics, GUI components, and layout managers. A new event model was introduced with JDK 1.1.
java.awt.datatransfer Inter-application data transfer support, including clipboard cut-and-paste.
java.awt.event Classes and interfaces for the new AWT event handler.
java.awt.image Image processing classes.
java.awt.peer Interface definitions for GUI components and platforms.
java.beans The JavaBeans API for creating reusable software components. java.io Input/output classes: A relatively large number of classes for I/O.
java.lang Central Java language classes: DefinesObject, Class, and primitive types.
java.lang.reflect Classes that allow a Java program to examine Java classes and to "reflect" on its own structure.
java.math Two classes that support arithmetic on arbitrary-size integers and arbitrary-precision floating-point numbers (important for cryptography).
java.net Networking classes.
java.rmi Classes and interfaces for Remote Method Invocation.
java.rmi.dgc Distributed garbage collection.
java.rmi.registry Classes and interfaces for tracking, naming, and advertising remote objects.
java.rmi.server The heart of the RMI system.
java.security Classes and interfaces that define fundamental cryptographic services. (See Chapter 3), JAVA 2
java.security.acl Access control list interfaces.
java.security.interfaces Interfaces required for the Java Security API’s implementation-independent design.
java.sql Java Database Connectivity (JDBC) API.
java.text Classes and interfaces for internationalization.
java.util Miscellaneous but critical classes: These classes are required for many others.
java.util.zip Classes for manipulating zlib, ZIP, and GZIP file formats.
The predefined Java classes provide enough functionality to write full-fledged programs in Java. Using the pre-defined classes as primitives, it is possible to construct higher-level classes and packages. Many such home grown packages are available both commercially and for free on the Net.
The World of Java Applications
In the early days of Java’s popularity, most Java programs took the form of applets, small programs that were attached to Web pages and loaded and run in Web browsers. As Java developed, people began to write substantial applications in Java, using it simply as an improved version of traditional languages such as C.
Java has always been good for more than this, and the world is now catching on to that fact. Java is really a good platform for any application that needs to be extended or customized, perhaps across the network, after it is deployed. A browser is only one example of such an application.
Another increasingly popular use of Java is in Web servers. Many servers have extension mechanisms, but the Java Servlet API provides a particularly flexible and compelling vehicle for extending a server with new application-specific or site-specific functions. Most major Web servers now support the Java Servlet API. Compared to browsers, servers present more difficult security challenges, since servers have more stringent reliability requirements and store more valuable data.
Java’s features also make it a good platform for creating new server-type applications. With natural support for multithreading, database access, and networking, Java gives developers a natural leg up in designing such applications. For these reasons, there has been an increasing use of Java in enterprise computing.
One common structure for such systems uses a "three-tier" architecture. A traditional database server acts as the "back end" tier, storing and managing the data needed to support a business application. The middle tier is a Java-enabled specialized server that interacts with the database and implements the "business logic" needed to manage client interactions with the system. The "front end" tier is a Java applet that runs in the client’s Web browser and provides a convenient user interface so that users can interact naturally with the system. Three-tier systems put together several uses of Java, and as a result face a wide array of security issues.
In addition to all of these applications in traditional computers, Java is being deployed in embedded devices such as smart cards, key rings, and pagers. Embedded applications are often involved in electronic commerce systems, adding yet another series of twists to our security story.
The growing variety of applications is reflected in the subject matter of this book. While the first edition focused almost exclusively on applet security issues, this edition encompasses the full breadth of today’s Java applications. We want to provide you with the information you need to know to maintain security while building, deploying, managing, and using up-to-date, Java-based systems. As Java has gotten down to business, so has this book.
Trust, Applets, and Applications
Java is much more than simply a language for creating applets. In the early days of Java (less than a handful of years ago), it was important to distinguish applet code (which was typically treated as untrusted and relegated to the sandbox) and application code (which was typically treated as fully trusted built-in code). This distinction is no longer a useful one.
An alternative way to carve up the Java program space is to think about code in terms of levels of trust. Programs that are more trusted can be allowed to carry out potentially dangerous acts (like writing files). Programs that are less trusted will have their powers and permissions curtailed.
If we think about Java programs this way, it is still possible to make sense of the old distinction between applets and applications. Java applets are usually, though not necessarily, small programs meant to be run in the context of a Web browser. Obviously, applets involve the most client-side (or user) security concerns of any Java programs. In fact, Java’s security policies originally existed in order to make applets feasible. The Java runtime enforces severe limitations on the things that applet classes may do [McGraw and Felten, 1996]. See www.javasoft.com/sfaq and Chapter 2 for details. In terms of the new trust-based distinction, applets are clearly treated as untrusted. This makes sense, since the origin of an applet is often unknown or unfamiliar.
In the early days of Java, Java applications had no such restrictions. In terms of our trust distinction, applications in Java before JAVA 2 were treated as completely trusted code. That meant applications could use the complete power of Java, including potentially dangerous functionality.
The reason the old distinction between applets and applications no longer makes sense is that today, applets can be fully trusted and applications can be completely untrusted. (Note the use of the word can in the previous sentence; we don’t mean to say that applets are always trusted or that applications are never trusted.) In fact, depending on the situation, each and every Java program can be trusted, partially trusted, or untrusted. Sound complicated? That’s because it is.
With the introduction of JAVA 2, Java includes the ability to create and manage security policies that treat programs according to their trust level. The mechanisms making up the base sandbox are still under there somewhere, but they serve merely as a default situation to handle code that warrants no trust. The interesting thing is that code that is partially trusted can be placed in a specially constructed custom sandbox. That means a partially trusted applet can be allowed to, say, read and write a particular file, or make a network connection to a particular server. This is good news for Java developers who were chafing under the constraints of the restrictive original sandbox.
Figure 1.6 illustrates the way in which the old applet/application distinction can be recast in terms of black-and-white trust. It also shows the impact that JAVA 2 has on the black-and-white trust model, transforming it into a shades-of-gray trust model.
Figure 1.6 From black-and-white to shades-of-gray.
The distinction between applets and applications found to be useful during the JDK 1.0.2 days no longer applies to mobile Java code based on the JAVA 2 model. In fact, all along the real distinction behind the scenes was between fully trusted code and fully untrusted code. A black-and-white distinction between trusted code and untrusted code underlies both JDK 1.0.2 and JDK 1.1. By contrast, the JAVA 2 approach to trust management implements a policy-oriented shades-of-gray architecture. Under JAVA 2, code can be constrained or unconstrained regardless of whether it is applet or application code.
The Many Flavors of Java
There are currently a large and growing number of Java systems running the gamut from Java gizmos (including Java rings), through smart cards with built-in Java interpreters, to complete Java Development Kits and IDEs. As with any platform meant to interact in a networked world, there are security concerns with each flavor of Java. This book will discuss security risks that apply to all flavors of Java, but will focus on JAVA 2 and Card Java 2.0.
Counterintuitively, Java is both growing and shrinking at the same time. The JDK, now up to version 1.2, is doubling in size with each major release. At the same time, embedded Java systems like Card Java 2.0 are stripping Java functionality down to bare bones. Both of these moves have important security implications. JAVA 2 involves fundamental changes to the Java security model as the Java sandbox is metamorphosing into a trust-based system built on code signing. Card Java 2.0 removes much of the sandbox, leaving smart card applets more room to misbehave.
All of Java’s built-in security functionality, including the recently added authentication and encryption features (which began to appear with JDK 1.1), are available to Java application developers. This functionality makes it possible for an application to establish its own security policy. In fact, Java-enabled browsers do just that, determining the security policy by which all applets that run inside them must abide. For obvious reasons, an applet is not allowed to change the browser’s (or for that matter, any application’s) security model!
Security risks fall into four basic categories: system modification, invasion of privacy, denial of service, and antagonism. These four categories of risk are discussed in detail in Chapter 2. The first two of our risk categories are handled moderately well by Java; the second two are not. Risks are particularly egregious in Java since exploiting vulnerabilities is simply a matter of booby-trapping a Web page with a malicious applet or two. Chapter 4, "Malicious Applets: Avoiding a Common Nuisance," and Chapter 5, "Attack Applets: Exploiting Holes in the Security Model," discuss two distinct forms of hostile applets. Java applets with bad intentions are the equivalent of every security administrator’s nightmare—exploit scripts [Garfinkel and Spafford, 1996].
Java’s designers are well aware of many of the risks associated with mobile code. To combat these risks, Java was specifically designed with security concerns in mind. The main goal was to address the security issue head-on so that naive users (most of the millions of Netscape Navigator and Internet Explorer users) would not have to become security experts just to surf the Web.
In its default form, Java presents a multitiered approach to security. At a general level, the tiers include:
• Restricted access to file systems and the network
• Restricted access to browser internals
• A set of load time and runtime checks to verify that byte code is following the rules
• A system for signing code and assigning it some level of capability.
The Java security model will be detailed in Chapter 2 and Chapter 3.JAVA 2Many claims have been made about the security of the Java language. We will try to separate reality from marketing hype in order to better understand the Java security model.
Java also provides a set of tools with which a developer can produce security-critical code (for both applets and applications). In addition to a number of advanced language features like array bounds checking and byte code validation, Java provides:
• A set of cryptographic APIs for standard algorithms
• Cryptography engines that provide the guts for a small subset of the APIs
• A strong, stack-based security system.
Although this book is not just a guide to Java’s security APIs, we will discuss Java’s security functionality in detail. In particular, we will emphasize that no computer language as powerful as Java makes writing security-critical code automatic or easy.
How Does Java Security Stack Up?
ActiveX Security Issues
The first thing to know about ActiveX is that it does not have an enforcement-related security model. It has a trust model that may be able to help you implement your own security policy. So the real question is: How does a trust model like ActiveX’s compare with a sandbox like Java’s?
Sandboxes and Signatures
There are two major approaches addressing the security concerns raised by mobile code systems: sandboxing and code signing. The first of these approaches, sandboxing, is an idea embraced by early implementations of Java (say, JDK 1.0.2). We extensively cover the Java sandbox in Chapter 2. The idea is simple: Make untrusted code run inside a box and limit its ability to do risky things. That is exactly what the Java security model aims to do.
The second approach, code signing, is how the ActiveX Authenticode system works. Binary files, such as ActiveX controls or Java class files, can be digitally signed by someone who "vouches" for the code. If you know and trust that person or organization, you may choose to trust the code which they vouch for. It is important to stress the fact that code signing is completely a matter of trust; there is no enforcement mechanism protecting you once you decide to trust a piece of code. The trust model implements authentication and authorization. What this means is that there is no such thing as ActiveX security enforcement! That’s not to say signature-based trust models are not useful. They are. In fact, trust models will play an integral role in future security models for mobile code. Much more detail on code signing, especially as it relates to Java, is found in Chapter 3.JAVA 2
Code Signing and ActiveX
ActiveX is a high-profile form of mobile code promoted by Microsoft. Note that in practice its "mobility" is completely constrained to one platform, however. As it is actually used today, ActiveX is language independent, but not platform independent, meaning that real ActiveX controls work only on Microsoft’s Win32 platform (Windows 95, Windows 98, and Windows NT). Technically, these controls could be recompiled for other platforms, but virtually nobody currently produces controls for non-Win32 platforms.
One caveat: Comparing ActiveX and Java is somewhat like comparing apples and oranges, even though everyone does it. ActiveX is a component-based software model while Java is a language/platform. ActiveX should really be compared with Java components, JavaBeans. (In fact, some argue that the real religious Holy War between Java and ActiveX is destined to take place in the middleware arena and will be decided by the battle of component models [Lewis, 1998].)
ActiveX has been roundly criticized by computer security professionals since its approach to security is seen as lacking. Unlike the base Java security situation, in which an applet has to run in the sandbox and is limited in the sorts of things it can do, an ActiveX control has no limitations on its behavior once it is invoked. The upshot is that users of ActiveX must be very careful only to run completely trusted code. On the other hand, Java users have the luxury of running untrusted code fairly safely.
The ActiveX approach relies on digital signatures, a kind of encryption technology in which arbitrary binary files can be "signed" by a developer, distributor, or certifier. Because a digital signature has special mathematical properties, it is very difficult to forge. That means a program like your browser can verify a signature, allowing you to be fairly certain who vouched for a piece of code (as long as people are carefully guarding and managing the private keys used to sign code). To make things easy, you can instruct your browser always to accept code signed by some party that you trust, or always to reject code signed by some party that you don't trust. The signature also supplies data integrity, meaning it can ensure that the code you received is the same as the code that was originally signed. Signed code cannot be easily hijacked and modified into a Trojan Horse.
The ActiveX system provides a black-and-white trust model: Either you trust the code completely and allow it to run unhampered on your machine, or you don’t. That means trusting the wrong sort of code just once is all it takes. Once an attack control runs on your system, it can rewrite your security policy in such a way that all future attacks will work. Of course, it can do anything at all, so this is only one of zillions of attack scenarios. Serious attacks using ActiveX have been seen in the wild (although their use is not widespread). For an explanation of these attacks and more on ActiveX insecurity, see Anup Ghosh’s book E-Commerce Security: Weak Links, Best Defenses [Ghosh, 1998].
Sandboxes versus Signatures
Do digital signatures make ActiveX more attractive security-wise than Java? No, especially in light of the fact that digital signature capability became available in Java's JDK 1.1, and in combination with fine-grained access control plays a major role in JAVA 2 security. That means in Java, you get everything that ActiveX is doing for security plus the ability to run untrusted code fairly safely.
Another significant factor is that the sandbox approach is more robust in the face of accidental bugs in mobile programs. Even if the sandbox isn’t bulletproof, it will most likely prevent a bug in a mobile program from trouncing important data or programs by mistake.
As we shall see in Chapter 3JAVA 2, when combined with access control, code signing allows applets to step outside the security sandbox gradually. In fact, the entire meaning of sandbox becomes a bit vague. As an example of how Java code-signing might work, an applet designed for use in an Intranet setting could be allowed to read and write to a particular company database as long as it was signed by the system administrator. Such a relaxation of the security model is important for developers who are chomping at the bit for their applets to do more. Writing code that works within the tight restrictions of the sandbox is a pain, and the original sandbox is very restrictive.
Microsoft’s Authenticode and Security Zones
When a signed ActiveX control is downloaded, the browser detaches the signature block (which is a signed one-way hash of the control packaged together with a standard X.509 certificate issued by a certificate authority) and performs checks on the identity of the signer using Authenticode. This is a two-step process. First the certificate is examined by checking the certificate authority’s identity. Then the one-way hash is checked to ensure that the same code that was signed was the code that arrived. Note that these checks say nothing at all about whether a control will or will not behave maliciously. They only check the identity of the signer and that the code has not changed since signing.
Microsoft Internet Explorer 4.x implements a security zone concept meant to ease the management of security policies for signed content such as ActiveX controls and Java applets. The system organizes Web sites into four "zones of trust" (or more if you customize): Local intranet zone, Trusted sites zone, Internet zone, and Restricted sites zone. Each zone can be configured with security levels of: High (most secure), Medium (more secure), Low, or Custom. The idea is to divide Web sites into these zones and assign the zones varying levels of trust.
Figure 1.7 shows a dialog box from MSIE that allows a user to manage Authenticode security zones.
Figure 1.7 Authenticodeís signature-based trust model implements the concept of security zones in order to aid in managing mobile code.
Microsoft Internet Explorer provides a dialog box that users can access to manage security zones. Though the importance of powerful policy management tools cannot be overstated, some security professionals complain that allowing a user to set security level is not a good idea—especially if high security correlates with high level of annoyance (through implementing, for example, too many security queries).
Zones are a useful tool that can help make a security policy more coherent. The concept may be particularly useful in non black-and-white policy situations currently beyond the scope of ActiveX. We think security zones are a useful tool that Java security systems beyond Microsoft’s should support as well.
In ActiveX with security zones, the security policy itself remains black and white: A mobile program is either fully privileged or completely banned from the system. Since most users are inclined to run cool-sounding code just to check it out regardless of the risk, popping a dialog box in front of a user and requiring an instant security decision is not a good idea. As one of the authors (Felten) is known to say, "Given a choice between dancing pigs and security, users will pick dancing pigs every time." The Princeton team correctly warns that relying completely on a human-judgment- based approach to security in not likely to be as successful as blending judgment with technology-based enforcement, as newer Java systems do. See Figure 1.8.
Figure 1.8 "Given the choice between dancing pigs and security, the world will pick dancing pigs every time."
The dancing pigs applet, available through the book’s Web site (www.rstcorp.com/java-security.html), demonstrates the use of digital signatures in Java. See Appendix C.
One way in which Authenticode addresses this problem is to put the security decisions in the hands of a system administrator. Using the MSIE Administration Kit (IEAK), an administrator can preinstall a list of permitted certificates and block the installation of others. This is a step towards centralizing security policy management (which is something most corporate users demand). However, in the end, the ActiveX model is still only a trust model. Just for the record, Netscape now includes a similar site-wide policy administration system.
We discuss these issues of trust, identity, and signatures again in more detail in Chapter 3, JAVA 2 though the focus is on Java and not ActiveX.
More on ActiveX Security
The Princeton Team has written a FAQ, reprinted in Appendix A, called Security Tradeoffs: Java versus ActiveX, in which a number of common questions about Java and ActiveX are answered. On the Web, the FAQ can be found at
Two other good places to look are in Chapter 2 of E-Commerce Security by Anup Ghosh [Ghosh, 1998] and page 18 of Web Security Sourcebook by Avi Rubin, Dan Geer, and Marcus Ranum [Rubin, Geer, and Ranum, 1997].
• Track a surfer’s history, secretly keeping tabs on all sites visited by a user and reporting back to a collection site
• Read directory listings, learning about a Web surfer’s file system and reporting back to a collection site
• Steal files, mailing the stolen goods back to an attacker
• Construct Java tags, circumventing systems that attempt to block Java applets by removing the
What Does All This Have to do with Java?
The important take-home message of this section is that Java security concerns do not exist in a vacuum. If someone tells you that you should disable Java, but pays no attention to these other threats, he or she is not doing you much of a favor. The truth is, there are much scarier things than Java out there. In fact, many of the attacks we have touched on here pale in comparison to security concerns raised by a Windows 95 PC connected to the Internet. Try to put all of the security concerns relevant to you on the same scale, and address the biggest risks first.
Where to Find More Information on Java
Java is growing rapidly, and keeping up with it requires as much energy as looking after a herd of two-year-olds (believe us, we know). Keeping up with the edge is just as important for security purposes as it is for any other. Here are some resources that can help make a time investment worth it.
Java on the Web
An excellent place to start learning about Java is the Web itself. The first URL to check is JavaSoft (java.sun.com). Also useful are developer.com (www.developer.com) and JavaWorld (www.javaworld.com). MindQ sells a set of excellent CD-ROMs that provides a multimedia introduction to programming Java applets and applications (among other issues). See their Web page for details at www.mindq.com. (MindQ produced the authors’ Java Security CD-ROM as well.) To discover some of the many other Java resources on the Net, search for Java at Yahoo! (www.yahoo.com) or on AltaVista (www.altavista.com). Also see two collections of security-related Java links put together by the authors at www.rstcorp.com/java-security.html and at www.cs.princeton.edu/sip. The references section of this book includes a complete listing of all URLs cited throughout the book.
The number of books on Java is growing almost as fast as the Web itself, and the Java shelf is groaning under their combined weight. For a comprehensive list, see lightyear.ncsa.uiuc.edu/~srp/java/javabooks.html. We have had a chance to use a few of them as Java coders. Here are four, with a brief review for each:
Core Java Volume 1—Fundamentals [Horstmann and Cornell, 1997]. This is a good book; big, but definitely useful. In fact, Core Java got so big that it split into two volumes for the JDK 1.1 edition. It is full of comparisons to C++ and Visual Basic, including useful pictures. The authors provide implementations for other classes that are not in the Java libraries, but are commonly used.
Inside the Java Virtual Machine Specification [Venners, 1997]. For anyone interested in the inner workings of Java’s Virtual Machine, this is the book to get. As we’ll see, Java applet security boils down to what byte code is allowed to do and how its behavior can be constrained. That means that learning about how the VM does its thing is a useful exercise for those people concerned about security.
Java in a Nutshell, second edition [Flanagan, 1997]. This book remains everyone’s favorite (well, every developer anyway), probably because it is so useful. O’Reilly is famous for their API books and, true to form, this book provides an extensive API for the packages provided by Java. This makes it excellent for a quick desk-side reference. There are some examples, but if you learn best by examples, you should consider Java Examples in a Nutshell [Flanagan, 1997]. Both books are equally useful for beginners and more advanced Java programmers.
Java Network Programming [Hughes, Shoffner, and Winslow, 1997]. One of the best reasons to use Java as a development platform is to take advantage of its built-in networking ability. This excellent book is filled with hands-on examples that are included on a CD-ROM. Of particular interest to security buffs, a number of cryptography algorithms are presented. Note that there is an O’Reilly book of the same title (this one is from Manning); however, this one is the one to get.
Java Security Resources
We’re glad to say the amount of information available on Java security is also growing. There are both a number of books available and a large number of Web sites. On the Web, we provide the most comprehensive and up-to-date hotlist¾ the Java Security Hotlist—at
The hotlist, which has over 100 links divided into 9 categories, has been reproduced as Appendix B, "The Java Security Hotlist." Of course URLs are notoriously dynamic, and Java security is a fast-moving field. For the latest version of the hotlist, see the Web site.
The Secure Internet Programming Lab at Princeton also maintains a site with information on security alerts and ongoing Java Security research at www.cs.princeton.edu/sip/.
Java Security Books
For at least a year, the first edition of this book, Java Security: Hostile Applets, Holes, & Antidotes, was the only available book on Java security. Since that time, a number of other books have come out that address the topic. Of course, we are biased about which one is best, but we thought you might appreciate our opinions about the others anyway:
Java Security: Hostile Applets, Holes, & Antidotes [McGraw and Felten, 1996]. The first book on Java security. This book was intended to educate Web users about the risks of Java security. It includes a discussion of the base Java security model and the original Java security holes. We’re glad we wrote it.
Java Network Security [Macgregor, et al., 1998]. This book appeared in 1998 and includes information on JDK 1.1, but nothing on JAVA 2. The book has a number of technical errors and unintentionally misleading claims about security as well. If you want a copy of everything ever written on Java security, get a copy; otherwise this one is skippable.
Java Security [Oaks, 1998]. O’Reilly is well known for their developer-oriented books. This book fits the bill, as it provides both an API reference guide and a number of code samples. It is
almost up to date (the switch to the doPrivileged() API discussed in Chapter 3 is not covered by Oaks) and carefully details JAVA 2 functionality. One caveat: Oaks is an employee of SunJAVA 2 Microsystems and certainly toes the party line. The discussion of security risks and implications reflects this fact. Also missing is any treatment of Java security holes. Nevertheless, if you are a developer who wants to learn about the APIs and you don’t care too much about the bigger picture, this book is for you.
The Web Security Sourcebook [Rubin, Geer, and Ranum, 1997]. Although this is not a Java security book per se, many of the lessons this book teaches are entirely relevant to people interested in Java security. This is a practical, hands-on book that covers Web server security, mobile code, CGI, and more, written by security experts of the highest caliber.
E-commerce Security [Ghosh, 1998]. Java is often put to use in e-commerce systems, and of course, e-commerce systems must take security very seriously. This book provides essential data for securing your e-commerce system. It discusses common errors, real attack targets, and solutions.
Mobile Code Has Its Price
Having programs embedded in Web pages that can run on any platform is an excellent idea. But in order to get this power, users take a great deal of risk.
A Web surfer can click over to a Web page with an embedded applet that immediately and automatically begins executing. Often, the user doesn’t even know this is happening. This situation might not be so bad if the Java environment being used were 100-percent secure. However, to make Java really secure would require making it completely impotent.8
There is a price that must be paid for the power of executable content. This price is very similar to the price that must be paid in order to connect to the Internet in the first place. (In fact, if you decide Java security risks are too much to bear, you should ask yourself what you are doing connected to the Internet at all!) The bill is payable in terms of risk and exposure to attack. The question is, how much risk are you willing to take? How critical is the information on your machine? Our goal in writing this book is to arm the reader with the data that is needed to make an informed, intelligent decision about Java, both as a system for mobile code and as a development platform.
Downloading Mystery Code
How often do you download executable code from various unknown sites on the Net? Do you think about where the code is coming from and who wrote it? Do you know what it will do before you run it?
Even if you are particularly cautious about downloading binaries from the Net, the answers to the questions raised will undoubtedly soon change. Applets are cropping up everywhere. At the moment, surfing the Web with a Java-enabled browser is tantamount to downloading and running arbitrary binaries, albeit with some level of security provided by Java. Deciding whether or not this is a good idea is an important decision that is as personal as a financial investment strategy.
It is worth repeating that there is no such thing as perfect security. This is true for any system on the Internet, not just systems using Java. Someone will always be probing Java security, trying to find new ways around or through the existing system. In the real world, all you can expect is reasonable security. The solution to this conundrum is finding an acceptable tradeoff between functionality and security.
Playing the Cost/Benefit Game
The Internet is a dangerous playground. Java offers an intriguing approach to the problem of security by neither ignoring it entirely (as most languages do) nor being completely paralyzed by it. Deciding what level of risk to incur is really a matter of weighing the potential costs of using Java against the clear benefits of using Java. Making an informed and intelligent decision requires understanding both aspects of the situation. Business people are always weighing costs and benefits when making complicated decisions. The same sort of careful consideration that goes into forming a business plan should also go into the formulation of a Java use policy.
The Java hype machine has been exceptionally good at broadcasting the benefits of Java. It have been successful largely because Java really does have vast potential. On the other hand, the advertising has been slightly less straightforward about the risks. (To this day we hear claims that Java is 100-percent secure, or that there is no need to worry about Java security.) This may be because the risks are complicated and sometimes difficult to understand. Computer security is a new field to many users, and few people are aware of all the issues. As Java applets become ubiquitous, it behooves us to become more aware of security issues. Ignorance is not bliss.
Assessing the Risks
Now that the basics of the Java environment have been covered, you are ready to examine Java security in earnest. It is only after understanding what the security model is, how it works, and how it doesn’t, that you can truly begin to assess the security situation.
People should think carefully about using Java even casually with a Java-enabled browser. This book will present some of the facts associated with Java security so that you may decide when, where, and how to use Java. Unfortunately, there is no black-and-white answer to the question: How and when should I use Java?
1Both the popular Netscape Navigator browser and the Microsoft Internet Explorer browser are capable of running Java applets.
3ARPA (now DARPA) is an acronym for the United States Department of Defense’s Advanced Research Project Agency that sponsored initial research on networking computers. DARPA currently supports many research projects in computer security, including work by the authors.
4All Netscape Navigators since 2.0x and Microsoft Internet Explorers since 3.0 include a Java VM that can interpret the Java byte code making up a Java applet.
5Note that many of the lessons of this book apply directly to all of these mobile code since the crux of the security problem is the idea of running untrusted code safely.
6These limitations had mainly to do with the fact that CGI scripts run on the server side, whereas Java applets run on the client side. CGI scripts trade off client-side security risks for risks induced on the Web server on which they reside. They are a common target of cracker attacks. See [Rubin, 1997] for more.
7Some experts’ opinions about Java and reliability differ, however. For an interesting critique of Java, see [Lewis, 1996].
8Keep in mind that the most secure machine is a machine that is kept "off" at all times, has its hard disk wiped, and is buried in a hole filled with concrete. Of course a machine this secure is also useless.