Introduction to Java and Security

An Overview of Java Security

The purpose of this chapter is not only to introduce the themes of the book to those who will later read the more detailed chapters that follow, but also to act as a brief overview for the intelligent non-specialist who does not need all the details. This is because the focus of the book is on helping people to deploy Java in a secure way. There are many people involved in that - managers, administrators, developers, systems programmers, users - all of whom play a part.

What Java Does

What Java does is to solve the problem of executable content. What's that? Well, the early sites on the Worldwide Web were static: pictures and text. That was revolutionary enough. The richness of the pages was a revelation to anyone used to the usual staid appearance of information downloaded from a server; the hypertext links, which made cross-referencing easy, made it a more useful information source than an encyclopedia; and the amount of information available was staggering. But if you wanted a program to run, you had to send a data file to the server where that program was - you filled in a form on the screen, clicked the send button, and waited for the result.

Some programs are better run on the client than on a server. So why couldn't part of the content of the Web pages be executable? Why couldn't a page comprise some text, some pictures, and some programs that run on the client? There were two reasons:

  1. It would be dangerous from a security point of view. There are enough viruses on the Web anyway. With executable content, you might not even realize that you were downloading potentially dangerous code.
  2. The programs might not run on a particular operating system. One of the joys of the Web was that you could choose whatever client system was right for you and download pages running on a completely different system.
But executable content is not just cute - it is extremely valuable:
  • Executable content can make a Web page much more exciting. This is what Java became well known for in its early days: dancing cartoon characters, bouncing heads, ticker tapes. You can't do these if all the programs must run on the server. Some of the early examples were indeed just cute - they showed what the technology could do, not why it was important - but appearance, excitement, and even cuteness are important in attracting customers to a business site.
  • Many dialogues with a customer are unbearably slow if you have to communicate with a Web server at each interaction. With executable content, the dialogue - an insurance proposal, a request for a credit card, a browse through a catalogue, or whatever - can be completed on the client machine, and the resulting transaction sent across the Web.

Java makes executable content possible while solving the problems noted above by having three components:

  1. A Java Virtual Machine ( JVM) designed to prevent the downloaded code (usually called an applet) from tampering with the client system. The applet runs in a protected space, known informally as the sandbox, and has only limited and always strictly controlled access to the surrounding system. This is to meet requirement 1 above.
  2. A set of bytecodes - virtual machine instructions - which are interpreted by the JVM. You have to have these to prevent the applet from jumping outside the sandbox, but they have a benefit of their own. Since they are machine-independent, if you have a JVM for your workstation, then you can run any applet from any server, satisfying requirement 2 above.
  3. A high-level object-oriented language in which to write the classes that make up the applets. This is a language similar in many ways to C++ with some functions (such as pointers) omitted because they could be used to escape from the sandbox.

There is now a Java Development Kit ( JDK) - comprising JVM, compiler, and basic classes - for most operating systems, and most Web browsers contain a JVM, so executable content is now real.

So far, we have concentrated on executable content and on the downloaded code known as an applet. Java high-level language, however, has wider uses than just applets. It is a general-purpose language, a well designed object-oriented language, in which you can write any program you like.

A Java program which is loaded locally, rather than from the Web, is called an application. Because it has not come over the Web, it is not constrained by the sandbox and can access the local machine, just like a program written in any other language. In this book we always clearly distinguish between applets and applications.

All you have to do is write an application once in Java, and you can run it anywhere that has a JVM. This makes it very useful for people writing applications which will be used by a wide variety of users - quite independently of whether they will ever be downloaded from the Web.

Java Is Not an Island: Java as a Part of Security

The geographical Java certainly is an island: a separate part of Indonesia. But Java the computer system is not something separate from the other components that make up the total system. So it is essential that the security of Java is seen as being one part of the security of the whole. This is hardly a new message. More than 100 years ago, Conan Doyle was ridiculing an approach to physical security that fitted a top-grade door lock and left the windows unsecured.

What this means for Java security is that it must be holistic , adequate and perpetual .

First, Java security must be holistic. An attacker who wishes you harm (rather than one who wants to prove his own cleverness) will focus on the weak links in the security, so the security of a system that uses Java must be reviewed as a whole, following the flows of data and application, and considering the potential for attack or accident at each point. Specifically, if Java is being used to pass applets over a shared network like the Internet, then you have to consider:

  • Private network protection, using a firewall and allied security policies
  • Private data protection, using encryption to shield data as it flows over the public network
  • User authentication, using digital signatures, or protected passwords

Secondly, Java security must be adequate. It has to be strong enough for the purpose in hand: Java must not be the weak link. But there is no need to spend extra to make it far and away the strongest link, unless either:

  • Your potential attackers don't just want to crack your system, they want to crack your Java system, or
  • Your users have a particular fear of Java, and you need to reassure them (security has to match levels of threat and worry, as well as, levels of potential loss)

So, if you cannot put fastenings on your sash windows, you don't need that Chubb lock on the front door.

Thirdly, Java security must be perpetual. This book will help you build a secure Java system to face today's perils of accident and attack. But those perils will change. So you must review your Java security - as a part of your overall security of course - regularly, to stay one jump ahead of potential attackers.

How well does Java meet those needs? Three points:

  1. Java architecture permits secure design . Java's use of a "sandbox" provides the capability of separating your computer from the applets you download. This is described in much more detail later. The point here is that the problems with Java that have been reported are problems with the implementation , not problems with the design .
  2. Java implementations respond to error reports. The attack applets we describe later were all reported by applet hunters; they come, not from incidents of loss on the Internet, but from laboratory studies of how Java can be used and abused. The applet hunters have been as responsible as they are clever, and have alerted the Java implementors to the problems before telling the public. So normally you will hear of an implementation loophole at the same time as hearing of the fix. Thus any risk of using Java gets gradually less as loopholes are closed.
  3. Nothing in Java should permit complacency. Installers and users of Java must be as willing to respond as the implementors. That is, users must recognize that loopholes will be found and must be closed without delay.

In summary, provided that you have an implementation that is free of known errors, and that you install, maintain and review Java carefully, you can reach levels of security which are appropriate for any business purpose.

Safety and Security

To enthusiastic object-oriented programmers, it is the Java language that is important. It contains a number of important differences from C++ which reduce the chance of writing a rogue program by accident, as well as making it more difficult to write a rogue program by design.

But, from a security point of view, it is the Java virtual machine that matters. The business benefits of Java are the security and portability of the JVM, and these come from the bytecodes, not from the Java source language.

So, we shall be more concerned with bytecode programs, which are different from Java source programs. All valid Java source programs can be compiled to bytecode programs, but there are bytecode programs that have no corresponding Java source. And, of course, it is possible to generate Java bytecode programs from other high-level languages. The first other language was NetREXX, a variant of the REXX language, and others have followed.

This difference between high-level and bytecode is both bad and good:

  • It is bad because people can circumvent the design features of the Java language. This was designed to produce well-behaved bytecode programs, a design that has limited security strength if an attacker can write directly in bytecode.
  • It is good because you can foil the decompilers. These take bytecode and generate Java source code - source code which is very readable because of the large amount of information a Java class file contains. To prevent people decompiling your valuable copyright code, you can modify the compiled class file so that there is no decompiled version. (We discuss this in detail in See Decompilation Attacks .

So the good features of the high-level Java language should be seen as safety features, not as security features.

Java as an Aid to Security

Sometimes, discussions of Java and security focus only on the perils of Java, as though there was only a downside to using it, from a security point of view anyway. But this is not the whole story. Java can be a great help to the security of a system, and can strengthen weak links, primarily because code distribution is a risky process .

Many applications need code running on the client in cooperation with code running on the server - for example, graphical front ends, or dialers to connect to the telephone network - and this code has to be installed there somehow. The distribution of this code is often a weak link in an online system, and it is usually much easier to attack this than to waste time trying to decrypt messages flowing over the Internet.

What is the danger? If this code can be tampered with, then, for example, a dialer number can be changed so that the client dials the attacker's site rather than the proper server. The client will never realize this because the attacker, acting as a " man in the middle" forwards all traffic between client and server, reading it as it goes. Or a virus can be introduced, or a host of other horrible possibilities.

The options for code distribution are:

  • To send a physical diskette or CD-ROM to the client
  • To have the client download the code over an existing network
  • To use Java

The safest of the three is Java. It isn't always suitable - the client must already have a network connection that is fast enough for the purpose - but it is by far the easiest to update with a new release, it is less easily intercepted than a physical distribution and, unlike a normal download, it is checked on arrival. Moreover, it can be signed.

The checking and signing of Java applets is central to Java security and (very) much more will be said about them in later chapters. In this introductory chapter, it is enough to describe briefly the three components of applet checking:

  1. The Class Loader is responsible for bringing together all of the different parts of the program so that it can be executed.
  2. The Class File Verifier (which includes the bytecode verifier) checks that the program obeys the rules of the Java Virtual Machine (but note that this does not necessarily mean that it obeys the rules of the Java language).
  3. The Security Manager imposes local restrictions on the things that the program is allowed to do. It is perfectly possible to customize this to allow applets limited access to carefully controlled resources, but in practice the browser vendors have implemented a version of the highly restrictive default that Sun supplies. This allows no access to the local file system, and network access only to the location from which the applet, or its Web page, came.

The way forward for allowing wider access is via the signed applets of JDK 1.1. You may wish, for example, to print something from an applet. You are unlikely to want your security manager to allow anyone to do that, but you might allow access to especially trustworthy people. So you download the applet; discover that it is encrypted with someone's private key; check the accompanying public-key certificate to make sure it is valid, and identifies someone especially trustworthy; decrypt the applet with that public key, and then allow it the necessary access.

One important thing that distinguishes Java from other forms of executable content is that it has both the web of trust that signatures bring and the three security components to validate the downloaded code. These precautions are taken, not because Java users are less trustful than others, but because even the most trusted of code suppliers sometimes make mistakes, or can have their systems compromised. Without the validation, a web of trust can become a web of corruption if any one trusted site is successfully cracked.

Java as a Threat to Security

So, in the absence of implementation errors, either on the part of the browser vendors or on the part of computer operators, administrators and systems programmers, Java should be safe. The browser vendors have a good reputation for responding to reports of flaws in their implementations, and one of the key purposes of this book is to help you avoid any slips in your installation.

If something does go wrong, then the most severe threat you face is system modification , the result of what are sometimes called "attack" applets. This is worse than someone's being able to read data from your system, because you have no idea what has been left behind. There could be a virus on your computer, or on any computer to which you are connected. Alternatively, some of your business data could have been modified so that it is no longer valid.

This is exactly the sort of thing that Java is intended to prevent, and its defences against attack applets are strong. They are equally strong against the next, still severe, threat of privacy invasion , in which read access rather than update access is gained. This does not leave you having to reinstall all your software and reassemble all your business data, but the loss can be serious enough. In addition to the exposure of business data, if your private key is compromised, then it can be used to sign electronic payments in your name.

Because Java has the strongest security for executable content, it has been seen as a challenge by security specialists, who find both the intellectual challenge exciting and want to help close any loopholes in Java implementations. Up to the date of writing, all the reported attack applets were developed by such specialists, not by malicious or criminal attackers.

There are another couple of, much less severe, threats against which Java does not have strong defences. The very essence of Java is that a program from a server will come down and run on your client with little, if any, intervention from you. What if the program is not one you want to run... if it is stealing your cycles?

The most extreme form of cycle stealing is a denial of service attack. The applet can use so much of the client's machine time that it cannot perform its normal function. This is the Java equivalent of flooding a company with mail or with telephone calls; like those nuisances it cannot readily be prevented - all you can do is find out who is responsible and take action after the event.

Less extreme examples of cycle stealing are the irksome, nuisance , applets. These run unhelpful programs intended to show how clever the author is and embarrass the owner of the client machine. They can even pretend to be you ( psyche stealing?), for example by sending e-mail that appears to come from you.

Java as Something to Be Secured

This is a different point of view again. From this point of view, Java applets are seen neither as aids to strengthening security weak links, nor as potential weak links themselves, but as assets that need to be protected. They can cost a lot to write and are valuable. They must not be copied and their use should be charged for.

This is an area which is still in its infancy. As was described earlier in this chapter, Java is a well-behaved language, and a Java class file can be decompiled to give a thoroughly intelligible Java program. So the same person who developed the Mocha decompiler has also developed the Crema obfuscator, which smudges the information in the class file so that the decompiler will no longer work. There is more on this subject in See Beating the Decompilation Threat .

However, the long term goal has to be to charge for the use of valuable Java applets. The most promising approach at the moment is the work on Cryptolopes, whereby the bulk of the applet is downloaded in encrypted form. Enough is unencrypted that the user can see what he is being offered, and request the decryption key, thereby agreeing to pay. This approach is discussed in See Java and Cryptolopes .

Writing Secure Java

The sort of applet described in the previous section - one that is an asset because it performs significant business function - is likely to need to communicate with the server it came from, and to do so securely. All sensitive communication over the Internet needs proper cryptographic protection, and so JDK 1.1 contains an application programming interface (API) for security.

There are two keys parts of this for writing applets that use cryptography. One of the reasons for the division is that some cryptographic functions are seen as being dangerous in the wrong hands. No government wants to provide organized crime, or terrorist groups, with a cheap effective way of communicating that the police cannot decrypt. Exactly how to prevent this is not so clear, so there are many different export and import rules for cryptographic products. The cryptographic interfaces are divided into two parts, JCA and JCE, which reflect the divide between exportable and unexportable cryptography. We discuss this in more detail in See Cryptography to the Rescue! .

Staying One Jump Ahead

To get ahead, the owners of a client or a Web site need to develop an overall security policy of which Java is a part, and implement it with care. They need to use the latest information on what is known about Java security. This is bound to change; realistically, Java is so young that it cannot be otherwise.

So how do they find the very latest information? Two key sources are the CERT Coordination Center, which is on the Web at http://www.cert.org/ and Sun Microsystems's list of frequently asked questions about applet security at http://java.javasoft.com/sfaq. This gets you ahead. Staying ahead means that the security policy should include regular checks of these sites, and regular reviews of which are the right sites to check.

Another part of staying ahead involves balancing security with stability. If an implementation error is discovered in the browser you use, and you see on the Web sites a description of the problem together with news of a new beta version of the browser to fix the problem, do you change to the new beta at once? Systems managers are traditionally very cautious about beta code: they want to see a lot of testing before they put it live on their production systems. This caution is one of the most important causes of the very high availability levels of modern systems, so systems managers are not about to change.

Traditionally, a change to include new function is forced to wait until it passes thorough testing, while a security change may be allowed through with less testing. It's a business decision, and it's worth including guidance in the security policy. The only way in which Java is different from all other areas of security, where similar business decisions must be made, is that news of a loophole can be spread worldwide extremely quickly, so the presumption should be that security fixes must go on quickly.

The Vigilant Web Site

The cure for abuse is proper use, not non-use. Executable content has such a great value to computer systems and to computer business that we need to do it properly, not to ban it.

Proper use of Java involves vigilance on everybody's part, including:

  • Vigilance on the part of the systems administrators who need to be sure that they can trust their sources
  • Vigilance on the part of the network administrators who need to protect against network attacks such as the man-in-the-middle
  • Vigilance on the part of applet developers who need to be sure that the tools they are using do not corrupt their class files: their workstations may not be production machines, but they must be properly protected

There is something of an irony in remarks one sometimes hears about how Java should be turned off, made by people who are happy to download a code patch or a driver from a Web site. It is similar to those who are deeply concerned about sending their credit card information over the Web, but would willingly hand a credit card to a waiter in a restaurant.

If Java is used with vigilance, then its unique combination of web of trust and code validation makes it more secure than forms of executable content which depend on the web of trust alone. And, of course, dramatically more secure than downloading natively executable code from the Web.