Java Developer's Reference
Writing Secure Programs
- A Bit of History
- Java Security Issues
- The Differing Security Aspects of Applets and Applications
- The Java Security Model
- The Future
As the first new language of the network age, Java's fundamental architecture is structured to confront a wide spectrum of security issues that previously have been addressed in a stop-gap, ad-hoc manner. Java was designed from the ground up to be able to have a fighting chance at giving users sufficient confidence in a program so that they would run it-even if it appeared on I.M. Rotten's home page-because they know a Java program can't cause them any major problems. As you write Java programs, you'll find that knowing how Java deals with security will help you save time and effort as well as help you avoid trying to do things that just aren't allowed, such as having an applet write a file to a random directory on the user's computer.
In ancient times, the 1970s, when programmers talked about security, it was job security through not commenting their code. The introduction of mass market computers brought about concerns of software piracy, so key disks and copy-protected disks became the weapons that programmers used to enforce security. The network revolution began with BBSs and moved on to LANs, online services such as AOL, and has so far culminated in the Internet and the World Wide Web. This progress has forced programmers to address a new spectrum of issues ranging from viruses (should my program detect when it's been infected?) to protecting users' data (how does my program protect the users' passwords?).
The expansion of the computer-using public is also a key factor
in current security concerns. In the past, people using computers
were usually experts who understood the details of their systems
and could rapidly respond to problems. Now computers are in the
hands of real people who just want to balance a checkbook or finish
the boss's report. Most computer users lack the expertise to rapidly
respond to security breaches. Additionally, the natural problems
of complex systems tend to be blamed on viruses by a public who
knows as much about how computers work as they know about the
details of smog tests.
My first contact with computer security put me on the wrong side of the law, or at least my high school administration. The high school computer used punched cards to input programs. Every deck had to be prefaced by a card you got out of a special box which determined your job's priority. Those cards didn't have anything printed on them, so I used the keypunch to print out what they "said." I discovered that they were just the numbers from 1 to 100.
I then made a new card with the number 2-I wasn't selfish enough to want the highest priority-and used it on all my jobs for the Fortran class I was taking. Well, my turn-around time sure improved. Unfortunately, one day a school official came storming into the computer classroom asking who Trinko was, a situation which I-a lowly student-didn't find to be very much fun. It turns out that the school payroll program had the number 2 card reserved. When they loaded it the computer, not the most brilliant of machines, shuffled my cards with the payroll cards. Fortunately, they were able to rerun the payroll job and no real damage was done.
Well, I learned my lesson. The point is that no security system is ever perfect, but it's very important to strive for perfection, because poor security can cause real problems. If those teachers weren't paid that week-which didn't happen-my exploitation of the security hole could have had significant impact on real people.
If Java succeeds as the Internet language, it will have to provide
a workable and effective security system. The reason is simple:
How many people would risk running an applet from some unknown
Web site if the applet could destroy their hard disk, make it
look as though they'd sent threatening mail to the President,
or steal their passwords? Even if individuals would take this
chance, companies would not, because a poorly secured Java applet
could destroy the effectiveness of their own system's firewalls.
A firewall is a computer that controls the flow of information between the Internet and a company's internal networks. Its mission is to let the folks on the inside access any information they need on the Internet while preventing folks on the outside from seeing what's on the company's computers. As a result, machines on the Internet can't establish connections with machines behind the firewall, but machines behind the firewall can establish connections with machines outside the firewall. Remote users can get behind the firewall if they have the appropriate security software/keycards-a daunting task even if you're authorized.
Figure 18.1 shows how a Java applet could circumvent a firewall.
Local machine A runs a hostile applet that it downloads from the
evil Hostile Applet Server, which resides somewhere out on the
Internet-perhaps in Chernobyl. That applet opens a network connection
to machine C, which contains valuable corporate secrets-like the
toupée vendor the boss uses-and steals all of the data,
which it sends back to the Hostile Applet Server. While it's doing
all this, the poor idiot working on machine A thinks he's just
playing some game.
Essentially, the firewall couldn't distinguish a Java applet running on an internal machine from a user using a browser on the same machine. As a result, the firewall wouldn't stop the applet from reading files from a company's machine and sending them to some other company's machine-not too good from a security perspective. Even worse scenarios arise if a Java applet can write files on the client system. The potential for Trojan horses and viruses would be unlimited. Clearly, people wouldn't be willing to wander around the World Wide Web as they currently do if any site could inflict this type of damage.
The bottom line is that, if Java weren't designed to provide security,
the probability of anyone using it on the WWW would be fairly
A Trojan horse is an application that pretends to be useful but actually performs some bad actions on a computer. An example might be a program that is supposed to be a freeware word processor but which actually erases your hard disk. Trojan horses are different from the products of software companies in that they are designed to cause problems.
If you download applications from the Internet, you probably check them with a virus scanner before running them. In general, using applications you get from an unknown source is buyer-beware activity where you know there are risks involved. Most of the time things are fine. I've found only two infected files in all my years surfing BBSs and the Net with my trustworthy Mac-but Mac viruses are much less common than IBM ones. However, if a problem occurs and you don't fix it quickly, you can lose lots of time and money. Because a Java application is no different than any other application, it has no more purely security-related constraints than any other language. Applets, though, are different.
Unlike the people who frequently download applications, most folks
who encounter Java applets are real people, not computer experts.
When you surf to a given URL, the applets on any of its pages
automatically load and execute-unless you've set your browser
to keep from running applets. You don't have a chance to run a
virus checker or to control the execution environment of the applet.
As a result, if you didn't know that Java applets couldn't hurt
you, you'd tend to set your browser to avoid running Java. But
if most browsers are set not to execute Java applets, a significant
part of the appeal of Java goes away. That's why there are extensive
security features in Java applets that aren't there for Java applications.
The next section walks you through them.
When you use Java to write an application, security restrictions are pretty much the same as writing an application in C or SmallTalk.
The first thing to realize is that although Java works on every platform, it's not the same-from a security perspective-in every browser. Netscape's Navigator has much more estrictive security rules than does Sun's HotJava browser. That's probably because UNIX users-HotJava's audience-are generally more familiar with security issues and computers in general than typical Mac or pc users. As a result, the current versions of Navigator hardwire more security limitations than are required by the Java security baseline. Because the various security restrictions are rapidly changing, the following list covers the various types of restrictions your customers are likely to encounter when trying to run Java applets:
- Cannot delete user files.
- Cannot rename files.
- Cannot create new directories.
- Cannot list the contents of directories. You wouldn't want applets to be able to snoop through your files and report back.
- Cannot get file information (such as modification date, size, or type).
- Cannot make a network connection to any machine other than the one that originated the applet.
- Cannot run any programs on the user's machine.
- Cannot work with any ThreadGroup other than its own.
- Cannot load native methods. Clearly, if an applet could load native C++ code, all security would go out the door.
- Cannot avoid warning banners on any windows your applet creates. This prevents an applet window from pretending to be something else, such your AOL signon dialog asking for your password. The banner is automatically added so you don't have to worry about it.
- Cannot create its own SecurityManager subclass.
Unless you're doing something fairly unusual, all of the security restrictions boil down to these two rules:
- You can't work with files on the user's machine unless he lets you.
- You can't connect to anything on the network other than the machine that originated your applet.
These restrictions are designed to ensure that an applet, no matter how malicious its developer is, can't cause you significant difficulty. The security rules prevent an applet from reading or modifying your file system and making network connections to sites other than the one that the applet came from. This prevents the sending of forged e-mail or the transfer of data from machines behind firewalls. Of course, if you use a browser that gives you more security control, you can overcome some of these protections. For example, if your browser lets you authorize writing of files and you accidentally include your root directory as an allowed place to write, an applet could then write files anywhere with potentially significant results.
One last thing is that, even with all of these restrictions, one class of attacks is still possible. Either through malicious intent or incompetent programming, an applet can execute what is called a denial of services attack on the user's computer. Such an attack consists of the applet using large amounts of system resources, thereby preventing you from doing anything else. This could be accomplished by opening several windows or initiating tons of threads. Although this is annoying, the worst it can do is force you to reboot your computer.
Of course, all of this assumes that Java is properly implemented. There have already been a number of bugs found in versions of Java prior to 1.0.2. Until Java settles down and the implementations are found to be bug-free on all platforms, there will always be a risk of security breaches due to implementation errors in Java itself. But since Java is designed to be secure, it's reasonable to expect that once the bugs are ironed out, Java will be very secure.
Now that you know what restrictions the Java security system enforces, you'd probably like to know how it does this. The answer is shown in Figure 18.2, which shows the four layers in the Java security model. Each layer provides a unique barrier to the construction and execution of applets with evil intent.
Now let's examine each of the layers in Figure 18.2 in detail.
One of the first barriers to rogue applets is the design of the Java language. Because Java doesn't have pointers and is strongly type checked-so much so that you can't cast an integer to an object reference-many of the traditional security holes found in C and C++ are plugged. For example, because there are no pointers, Java applets can't invade the memory space of another program. These architectural features are actually beneficial in that they eliminate the most common coding errors that cause problems in C++. In fact, the lack of pointers and the automatic garbage collection will probably lead to a factor of two or more reduction in software development costs for any application that doesn't require low-level control of the machine-such as a device driver-because of the time saved tracking down pointer-related errors in the code.
The compiler plays a role in this by enforcing the rules and prohibiting various types of potentially dangerous casts.
This is the heart of the Java security scheme. If someone figures out how to get past this, real trouble can arise. The basic job of this layer is to verify every program before it's run. This protects you against someone hand-coding a class file that violates the Java security rules or developing a compiler that doesn't enforce the Java security rules.
The ByteCode verifier is a very powerful guard which first verifies that the file is a properly structured Java class file. The next step is complex and involves proving certain theorems about the class. The process guarantees the following about the applet:
- It doesn't cause stack over- or underflows.
- Operators' arguments are of the proper type: An integer isn't being used with an operator that requires an object reference for example.
- Objects are only accessed according to the approved rules; for example, this refers to accessing private and protected methods.
- No casts that violate Java security rules are attempted.
This approach has a significant side benefit of making the interpreter run faster, because it doesn't have to check for any of these problems.
After a class has been verified, it can be loaded into the Java system. In order to prevent applets from replacing security-related classes and thereby breaking the security system, Java divides the namespace into several levels. Currently there are three levels: the local file system-most protected; the local network-middle protection; and the Internet-least protected. The class loader won't replace a class in a more protected level with a class from a less protected level. The really key classes, such as those that control I/O, are in the local level so no applet that is coming from another machine can override and replace them.
Additionally, the class loader prevents classes in one layer from accessing any non-public methods in classes in other layers. In a similar fashion, when multiple applets are loaded, they're placed in separate namespaces so that they can't interact unless they're designed to do so.
This is actually an abstract class that is designed to allow you to tailor the security policies that a browser or application will enforce. Applets can't modify the SecurityManager, but applications can extend it and define their own security policies. Your security policies, as determined by your SecurityManager, determine what types of dangerous operations an applet can perform. For example, the Netscape SecurityManager prohibits all file reading/writing, but other browser SecurityManagers could allow different levels of file access depending upon the source of the applet.
These four levels working together provide a nearly airtight defense against malicious applets. There are still some security problems (researchers have been finding a new problem every few months), but they are fairly difficult to exploit. In fact, the real problem is that, because the security system limits file and network I/O (a key reason for the wonderfulness of networks and computers), there are too many powerful and useful applications that can't be written.
Netscape and Sun have recognized the fact that the security model has to be extended so that users have more flexibility in controlling the privileges given to applets. After all, if you'll be able to download your next word processor as a LiveObject OpenDoc component over the Net, it's silly to restrict its access anymore than you would restrict Microsoft Word-although, given the behavior of Word 6, perhaps limiting its access wouldn't be a bad idea. According to the latest news from Netscape, the solution they're exploring is a way to certify applets via encrypted tags so that you would know that the applet is in fact one provided by someone you'd trust. Netscape has said version 4.0 will allow the browser to assign different privilege levels depending upon the level of trust an applet can have.
It's hard to know what the actual security system of the future
will be; things are changing too quickly. For example, in the
last beta of Netscape 3.0, a change in the security rules broke
a number of applets that used applet-to-applet communications.
One thing is sure: Maintaining a secure Java environment will
be a critical objective that all players-Sun and the browser vendors-will
As of this writing the Sun Security FAQ for Java can be found at http://www.javasoft.com/sfaq/index.html.
You've seen how Java is designed to protect the applet user from malicious programs. The four-tiered security system is designed to enable browsers to control the level of access to dangerous operations, while preventing problems. The future seems to hold a scheme for making trusted applets whose source is unimpeachably known. Those applets can be safely assigned more extensive privileges.