Java developers are constantly becoming frustrated because of unexpected encounters with Java security features. For example, a recent posting on comp.langs.java.security complained about difficulties in being able to open a network socket with Java. After reading the security introduction in the last issue of JDJ, it should be clear that allowing Web content to open arbitrary network connections on a workstation is highly undesirable. Not only could this circumvent existing security mechanisms, such as firewalls and IP address-based access control, but these network connections would appear to be initiated by the user, which could be embarrassing. Java applets are deliberately limited in their capability in order to protect users. Without these limitations, or some other protective mechanism, they would not be acceptable to corporate users.
Another recent posting in comp.langs.java.programming complained about not being able to do local file I/O with a Java applet. If you are still not convinced that placing constraints on Java applets is really necessary, let me review an example of what can happen without Java security controls. According to several recent reports, the Chaos Computer Club, a group of German hackers, demonstrated on a German TV program how ActiveX could be used for automated Internet theft. They put an ActiveX object in a Web page that, when viewed, searched a user's disk drive for the existence of Quicken. If found, the hostile code surreptitiously ran Quicken and added a new transaction. When the user next started Quicken, entered a legitimate transaction, dialed into their bank, entered the PIN and transaction numbers (both required by German banks) and pressed transfer, the bogus transaction was sent to the bank. While I can think of several good reasons why this particular hack is not likely to result in an epidemic of home finance hacking, the lesson is that uncontrolled external access to a PC can result in very undesirable consequences. Like ActiveX, Java can be used to embed executables in a Web page for automatic execution on a user's system. Unlike ActiveX, Java has a security model that constrains its behavior.
The Security Policy
The original vision of Java was to be an efficient language to support embedded systems. The security considerations of a TV set-top device, for example, are not necessarily the same as for a personal computer. The security policy underlying Java today is quite simple:
"In general, applets loaded over the net are prevented from reading and writing files on the client file system, and from making network connections except to the originating host.
In addition, applets loaded over the net are prevented from starting other programs on the client. Applets loaded over the net are also not allowed to load libraries or to define native method calls. If an applet could define native method calls, that would give the applet direct access to the underlying computer.
There are other specific capabilities denied to applets loaded over the net, but most of the applet security policy is described by those two paragraphs above."
Frequently Asked Questions,
Java applets are prevented from reading or writing local files or arbitrarily accessing the network, and most security experts agree that this should be sufficient. All of the publicized Java security failures have involved flawed browser implementations, and have not disproved this basic policy.
Security Failures In Real Life
UNIX is the most commonly hacked environment on the Internet. While much of this undesirable attention can be attributed to its ubiquity, UNIX has two characteristics that make it a favorite target. First, it is written in C. Suffering from extensive use of confusing pointers, weak type casting and lackluster garbage collection, it is no coincidence that C is the language chosen for the annual Obfuscated Code contest (the International Obfuscated C Code Contest has run since 1984). Second, many UNIX services must run as privileged code and most implementations of UNIX entrust applications like the print spooler (lpr) and the e-mail handler (sendmail) with full root privileges on the assumption that they will behave correctly. A typical UNIX hack involves sending some unanticipated input to a server application that causes a data structure overflow allowing some arbitrary string to be sent to the command interpreter. If the server application is running with superuser privileges, then the intruder can usually gain full control of the machine.
The Java security model is intended to protect against both of these eventualities. It is designed so that Java code won't break in unintended ways, and applets are run in a protected environment that limits damage in case failure does occur. Like the X Window System, Java reverses the client/server relationship. In one very significant way, a Java-capable browser is very much like a UNIX service: it responds to remote network input without allowing the remote entity full access to system capabilities. For browsers to safely run arbitrary applets received over the network, they must be able to run them in a limited environment that provides less capability than the browser itself has access to.
Making Cleaner Code
Java compilers are designed to prevent the creation of potentially dangerous code. While this might seem to limit the potential for clever programming, it provides an important benefit. It helps the developer create code that will be acceptable to the runtime environment. The compiler is not really a security feature, because it can easily be circumvented by hacking Java binaries or writing a new compiler, but it supports the Java security model by creating verifiable byte code.
Playing in the Sandbox
Web browsers provide the Java applet runtime support and are responsible for providing security. The runtime environment prefers being handed clean Java code, but always makes the assumption that the code could be unacceptable. Three main mechanisms are used to provide this security.
All applets loaded over the network are loaded by the applet class loader, which assigns a private namespace associated with the origin of the applet and maintains a separate and unique namespace for all classes loaded from the local file system. A Web browser has only one class loader and it cannot be modified, circumvented or replaced. If an applet could replace a built-in class, then it could circumvent the security policy, so the class loader prevents class spoofing by always searching for built-in classes first.
The applet class loader passes all applets through the bytecode verifier, which checks the integrity of each class file for unacceptable behavior:
Not only is Java a strongly typed language, but the verifier enforces type safety. Ensuring that byte code is well-behaved not only improves security, but allows the Java virtual machine interpreter to be more efficient.
- stack over or underflows
- invalid register access
- invalid bytecode parameters
- illegal data conversion
These two mechanisms provide a degree of robustness exceeding many existing TCP/IP-based services, but the third mechanism, the Java security manager, actually enforces the security policy. Like the class loader, a Web browser has only one security manager and it cannot be modified, circumvented or replaced. It's the security manager which prevents the reading and writing of files, prevents the deletion or creation of files and prevents access to other computers. The security manager really allows applets to do only four things. They can run, they can access the screen, they can accept input and they can connect back to their originating host.
To summarize, the security manager controls access to the file system, the network, the user environment and to system calls. The verifier, by ensuring that the bytecode is acceptable, protects allocated memory. The class loader maintains the distinction between internal and external code and prevents external classes from interfering with each other.
Just Browsing, Thank You
Remember that the onus is on the browser to protect itself and the client machine. The security policy is enforced by the browser and cannot be changed externally. While Netscape and Microsoft have chosen to follow Sun's lead in the implementation of their browsers, it's entirely possible to create a client that uses a completely different security model. The class loader and security manager are provided with the Java Development Kit, but they can be modified and they probably will be in the future.
In information security terms, the Java runtime environment protects the confidentiality and integrity of the system it is running on. It makes no claim to protect availability, and a number of hostile applets have demonstrated that it is easy for Java to hog all available system resources.
Intended for both browser users and applet developers, the most current text on this subject is Java Security: Hostile Applets, Holes, and Antidotes by Gary McGraw and Ed Felton, published by Wiley.
For detailed information on the verification process, see Low Level Security in Java by Frank Yellin (
About the Author
Jay Heiser is the Director of Internet Products for HomeCom Internet Security Services, where he is currently providing network security consulting to several major financial institutions and retail chains. He has lectured on information security in the US and Europe at events such as InfoWarCon, The Internet Conference, and FOSE. Jay also has animated several presentations on basic network security topics and made them available on the Web at http://www.homecom.com/services/hiss/LearnAbout.html. He can be reached at [email protected]