Chapter 3. Java and JavaScript

Java and JavaScript are both languages for adding interactivity to web pages. Both languages can be run on either a web browser or a web server (or even stand-alone). Both languages have a syntax that resembles the C++ language.

Despite these apparent similarities, Java and JavaScript are actually two completely different languages with different semantics, different user communities, and different security implications. This chapter explores the security issues in each language.

Java

Although today Java is widely thought of as a language for writing programs that are downloaded over the Internet to web browsers, it wasn’t designed for that purpose. Indeed, Java’s security model was largely added as an afterthought. To understand the security issues with Java today, it’s important to understand the history of the language.

Java’s history started in 1991 when a group of engineers at Sun Microsystems were hard at work on a stealth project designed to catapult Sun into the world of consumer electronics. Sun envisioned a future in which toasters, remote control systems, stereos, and cable decoder boxes were all programmed using a common computer language with programs that could be easily downloaded over a network. The stealth project was designed to leverage Sun’s experience with computer languages, system design, and silicon manufacturing to turn the company into a major supplier for this new world order.

The key to dominating this new world was a new computer language developed by James Gosling. Called Oak, the language was designed to produce programs that would be compact and highly reliable. Compactness was necessary because Oak programs were going to be downloaded over networks whenever it was necessary to change them. And reliability was necessary too, because programs in this language had to be able to run for weeks or months at a time without outside intervention: you can’t expect to dominate the market if you sometimes need to tell the average American that his toaster oven has to be rebooted to continue operation.

Instead of being compiled for a specific microprocessor, Oak was designed to be compiled into an interpreted bytecode that would run on a virtual machine. Simple economics drove the decision to use a virtual machine: a portable bytecode would allow a consumer electronics manufacturer to change its microprocessor without losing compatibility with existing programs. Unlike today’s desktop computers, the microprocessor would truly become a commodity.

The first test for Oak was an interactive cable TV decoder box that Sun was designing for Time Warner. In April 1993, Time Warner assured Sun that it would be awarded the contract for the interactive cable TV trial because it had superior technology. But on June 14, 1993, Time Warner awarded the set-top box contract to Silicon Graphics, Inc. It was perhaps just as well: interactive cable TV was a failure.[13]

In the months that followed, the Oak team repositioned their language for the world of CD-ROMs and multimedia publishing. Oak was designed to create compelling, multiplatform programs. Why not have those programs run on traditional PCs, Macs, and UNIX workstations? Right around that time, another multiplatform phenomenon was sweeping the computer industry: the World Wide Web. That was great for the Oak team: they had a language that was designed to be small and portable. The team quickly realized they could use the Web to download programs to an end user’s computer and have the programs run instantly on the user’s desktop.

In July 1994, Patrick Naughton, a member of the team, wrote a “throwaway” web browser to demonstrate the idea. Within a month, the browser was rewritten from scratch in Oak, and a system for running downloaded applets was designed and implemented. Eight months later, Sun formally announced Java and its HotJava web browser at the 1995 SunWorld tradeshow. That same day, Netscape announced its intention to license Java for use in the Netscape Navigator web browser.

Java the Language

Java is a modern object-oriented language that has a syntax similar to C++, dynamic binding, garbage collection, and a simple inheritance model. Although Java was largely promoted as a language for the World Wide Web, Java is in fact a general-purpose computer language that can be used for writing anything from simple five-line toy programs to complicated applications.

What initially distinguished the typical Java implementation from other computer languages is the run-time environment. Instead of being compiled for a particular microprocessor, Java programs are compiled into a processor-independent byte-code . This bytecode is loaded into a computer’s memory by the Java Class Loader . Finally, the bytecode is run on a Java virtual machine ( JVM).

The Java virtual machine can run Java programs directly on an operating system such as Windows or MacOS; alternatively, the JVM can be embedded inside a web browser, allowing programs to be executed as they are downloaded from the World Wide Web. The JVM can execute the Java bytecode directly using an interpreter. Alternatively, it can use a “just-in-time” compiler to convert the bytecode into the native machine code of the particular computer on which it is running. This whole Java cycle is depicted in Figure 3.1.

Java can also be compiled directly into machine code and run on a target system. Used this way, Java loses its run-time advantage of being able to run on any computer and any operating system that has a Java virtual machine, but it retains its advantage of generating code that has automatic memory management.

The Java cycle

Figure 3-1.  The Java cycle

Java Safety

From the beginning, the Oak team wanted to create a language that would encourage programmers to write code that was inherently reliable. Starting with C++, Gosling and his team removed many of the features from C++ that are confusing or commonly misused. In this way, they sought to increase the safety of the language and the sanity of programs written with it.

The main way that Java achieves reliability is by providing automatic memory management. Specifically:

  • Instead of forcing the programmer to manually manage memory with malloc( ) and free( ), Java has a working garbage collection system. As a result, Java programmers don’t need to worry about memory leaks, or about the possibility that they are using memory in one part of an application that is still in use by another.

  • Java has built-in bounds checking on all strings and arrays. This eliminates buffer overruns, which are another major source of C and C++ programming errors and security bugs.

  • The Java language doesn’t have pointers. That’s good, because many C/C++ programmers don’t understand the difference between a pointer to an object and the object itself.[14]

  • Java only has single inheritance, making Java class hierarchies easier to understand. And since Java classes can implement multiple interfaces, the language supports many of the advantages of multiple-inheritance languages.

  • Java is strongly typed, so you don’t have problems where one part of a program thinks that an object has one type, and another part of a program thinks that an object has another type.

  • Java has a sophisticated exception handling system.

All of these features combine to make Java a safe programming language: Java programs rarely misbehave wildly when given data that is slightly unexpected. (Instead, they simply generate an exception, which usually causes the program to terminate with a run-time error.) And because most security problems are the result of bugs and programming errors, it is thought that programs written in the Java language will be more secure than programs written in traditional languages such as C and C++.

Java Security

Java was not designed to be a secure programming language. Under Java’s original vision, programs would only be downloaded by an equipment manufacturer or an approved content provider. Java was designed for a closed programmer community and for a somewhat constrained set of target environments.

When Java was repositioned for the Web, security immediately became a concern. By design, the World Wide Web allows any user to download any page from anyone on the Internet, whether it is from an approved content provider or not. If web users can download and run a program by simply clicking on a web page, then there needs to be some mechanism for protecting users from malicious and poorly constructed programs.

Safety is not security

Having a safe programming language protects users from many conventional security problems. That’s because many security-related problems are actually the result of programming faults.[15] Java eliminates many traditional sources of bugs, such as buffer overflows.

But a safe programming language alone cannot protect users from programs that are intentionally malicious.[16] To provide protection against these underlying attacks (and countless others), it’s necessary to place limits on what downloaded programs can do.

Java employs a variety of techniques to limit what a downloaded program can do. The main ones are the Java sandbox, the SecurityManager class, the Bytecode Verifier, and the Java Class Loader. These processes are illustrated in Figure 3.2 and described in the following sections.

The Java sandbox, SecurityManager class, Bytecode Verifier, and Class Loader

Figure 3-2.  The Java sandbox, SecurityManager class, Bytecode Verifier, and Class Loader

Sandbox

Java programs are prohibited from directly manipulating a computer’s hardware or making direct calls to the computer’s operating system. Instead, Java programs run on a virtual computer inside a restricted virtual space.

Sun termed this approach to security the Java “sandbox,” likening the Java execution environment to a place where a child can build things and break things and generally not get hurt and not hurt the outside world.

SecurityManager class

If all Java programs were restricted so that they couldn’t send information over the network, couldn’t read or write from the user’s hard disk, and couldn’t manipulate the computer’s input/output devices, they would probably be nearly secure: after all, there would be little damage that the programs could do.[17] Of course, these limitations would also make Java a much less exciting programming environment: that’s because there wouldn’t be much of anything interesting that Java programs could do either.

Java uses a series of special classes that allow programs running inside the sandbox to communicate with the outside world. For example, the Java class FileOutputStream allows a Java program to open a file for writing to the user’s hard disk.

The creators of Java believed that programs that are downloaded from an untrusted source, such as the Internet, should run with fewer privileges than programs that are run directly from the user’s hard disk. They created a special class, called SecurityManager, which is designed to be called before any “dangerous” operation is executed. The SecurityManager class determines whether the operation should be allowed or not.[18]

Class Loader

Because most of the security checks in the Java programming environment are written in the Java language itself, it’s important to ensure that a malicious piece of program code can’t disable the checks. One way to launch such an attack would be to have a malicious program disable the standard SecurityManager class or replace it with a more permissive version. Such an attack could be carried out by a downloaded piece of machine code or a Java applet that exploited a bug in the Java run-time system. To prevent this attack, the Class Loader examines classes to make sure that they do not violate the run-time system.

Bytecode Verifier

To further protect the Java run-time security system, Java employs a Bytecode Verifier. The verifier is supposed to ensure that the bytecode that is downloaded could only have been created by compiling a valid Java program. For example, the Bytecode Verifier is supposed to assure that:

  • The downloaded program doesn’t forge pointers.

  • The program doesn’t violate access restrictions.

  • The program doesn’t violate the type of any objects.

Sun implements its Bytecode Verifier as a series of ad hoc checks. Sun claims that once a program has been proven to be correct, it can be executed with fewer run-time checks, and this allows it to run faster. Certified programs can also be compiled into machine code without risk, as the same set of instructions are guaranteed to be executed, no matter whether they are interpreted or compiled.

There are many problems with the Java security approach. These are described later in this chapter in Section 3.1.5.

Java Security Policy

Java security policy is complicated by the fact that the Java programming language is designed for two fundamentally different purposes:

  • Java is a general-purpose computer language for creating word processors, electronic mail clients, web browsers, and other kinds of productivity software. These programs might be resident on a user’s computer or downloaded from an organization’s internal web server.

  • Java is a language that is used to download applications from the Web that perform animations, create interactive chat systems, and perform complex calculations on the user’s machine.

These different purposes require fundamentally different security policies: you want to be able to read files on your hard disk with your word processor, but it is probably inappropriate for an applet that implements a chat system to do the same. This dual nature leads to a much more complicated security model, which in turn leads to more difficulty in enforcement.

Java’s original implementors envisioned three different security policies that could be enforced by web browsers that implemented the Java programming language:

  1. Do not run Java programs.

  2. Run Java programs with different privileges depending on the source of the program. Programs downloaded from web pages would run with severe restrictions. Programs loaded off the user’s hard drive would have no restrictions.

  3. No restrictions on Java programs. Allow the Java program to do anything at all with the computer’s hard disk, network connectivity, and anything else.

Sun’s HotJava browser implemented all three of these policies; the choice was left to the user. Most users chose policy 2. The complete list of restrictions for downloaded applets appears in Table 3.1.

Table 3-1. Some of the Restrictions on Downloaded Java Applets in the HotJava Browser

Restriction

Reason

Cannot read the contents of files or directories on the client computer.

Protects the confidentiality of information on the user’s computer.

Cannot write, rename, or delete files on the client computer.

Protects the user’s data from unauthorized modification.

Cannot initiate a network connection to a computer other than the computer from which the Java applet was downloaded.

Prevents a downloaded applet from probing for security problems behind an organization’s firewall.

Cannot receive network connections.

Prevents an applet from appearing to be a legitimate server on an organization’s internal network.

Cannot display a window without a special “untrusted” border.

Prevents applets from creating windows that appear to be system windows.

Cannot create a ClassLoader or SecurityManager.

Prevents subverting the Java type checking system and disabling all Java security checks.

Cannot run system programs.

Prevents running arbitrary code.

Sun’s Java policy was but one of many possible policies that could have been implemented. Java, after all, is a flexible language with fine-grained control over the actions of programs. Here, for example, are some policies that could have been set for network connectivity:

  • No network connectivity. A Java program could not access the network.

  • Limited network connectivity. A Java applet could only open network connections to the host from which it was downloaded.

  • Limited network connectivity. A Java applet could only open network connections to a host whose name appears in a set of preapproved hosts.

  • Limited network connectivity. A Java applet could only open network connections on a specified port or ports.

  • No restrictions for applets downloaded from particular machines. A corporation might want to use such a policy for code that is downloaded from the company’s internal “intranet” server, but still place restrictions on applets downloaded from other sources.

  • No restrictions for “signed” applets. Java applets that are digitally signed by an approved secret key have full access to the computer’s resources; unsigned applets are restricted. This policy might be used to allow access for applets from a company vendor.

  • Unlimited connectivity.

One of the problems with Sun’s original sandbox was that it blurred the distinction between the Java language and the security policies that could be applied.

Setting Java policy from Netscape Navigator 2.3

Netscape Navigator Version 2.3 followed Sun’s rather simplistic approach to Java security policy:

  • Java is either enabled or it is not (see Figure 3.3).

  • Java applets that are downloaded from the Internet are restricted in a number of ways. This includes not being allowed to touch the local file system, and only being allowed to create network connections to the computer from which they were downloaded.

  • Java applets that are loaded from the user’s local hard disk have full access to all features of the language.

Netscape Navigator Version 2.0’s simple approach to Java and JavaScript security: turn it on or turn it off

Figure 3-3. Netscape Navigator Version 2.0’s simple approach to Java and JavaScript security: turn it on or turn it off

Setting Java policy from Internet Explorer 3.0

Internet Explorer 3.0 implements a superset of Navigator 3.0’s policy:

  • Java is either enabled or disabled.

  • Programs that are downloaded from the Internet cannot access the user’s hard drive. These programs can only create Internet connections to the computer from which they were downloaded.

  • Programs that are loaded from the local hard disk have full access to the user’s computer.

  • Programs that are signed with an Authenticode software publisher’s key and approved by the user can also have full access to the user’s computer.

Setting Java policy from Netscape Navigator 4.0

Netscape Navigator 4.0 opens the Java sandbox, allowing downloaded applets more functionality and flexibility. However, it attempts to do so in a way that can be carefully monitored and controlled by the user. It does so using digital signatures and digitally signed capabilities.

Navigator 4.0 identifies a variety of different kinds of privileges that a Java program might need. These privileges can then be given to a program on a case-by-case basis. Navigator 4.0 further allows Java classes to be digitally signed by software publishers.

Giving programs capabilities in this way allows the Java environment to satisfy the “principle of least privilege:” programs should have the privileges necessary to perform the tasks that are expected of them, and nothing more.

For example, a game application might need the ability to read and write from a file containing previous scores and the ability to write directly to the user’s screen. However, it doesn’t need the ability to read and write any file on the user’s hard drive. A teleconferencing application might need “push-to-talk” access to the user’s microphone, but it doesn’t need the ability to surreptitiously bug the user’s workspace.

Rather than presenting the user with a collection of capabilities when a program starts up—“Do you wish to grant Dark Stalker physical screen I/O access, read/write access to C:WINDOWSFILESHIGHSCORE.STALKER, sound blaster access” and so on—Netscape has created a set of permissions “macros.” These allow a program to ask for, and receive, “typical game permissions.”

Finally, Netscape has created a system that allows permissions to be encapsulated within signed application modules. This might allow Dark Stalker to get physical screen I/O access through a library that had been signed by an approved software publisher, but would prohibit Dark Stalker from directly accessing the screen otherwise.

Setting Java policy from Internet Explorer 4.0

Internet Explorer 4.0 will also introduce a sophisticated capabilities-based system that uses code signing to extend additional privileges to Java applets.

Java Security Problems

In the spring of 1996, a trio of researchers at Princeton University searched for and found a number of security problems in the Java language. The team—Professor Edward W. Felten and graduate students Drew Dean and Dan S. Wallach—christened themselves the Secure Internet Programming (SIP) group and published several bulletins informing people of the problems that they had found. They also worked with Microsoft, Netscape, and Sun to correct the problems they discovered.

Most of the security problems discovered by the Princeton team were implementation errors: bugs in the Java run-time system that could be patched. But some of the problems discovered were design flaws in the Java language itself.

The good news for Java users and developers is that many of the security problems found by the Princeton team were addressed shortly after they were discovered. And there were no published cases of any of these flaws being used by an attacker to exploit the security at a victim site. The bad news is the fact that the Princeton team was able to find many security problems in a program that had been widely released on the Internet and was being used by millions of people.

Ideally, outside security reviews should take place before products are released, rather than afterwards. While the basic implementation flaws discovered by the Princeton team have been fixed, new features and releases will bring new bugs. Sun, Netscape, and Microsoft need to be more open with their internal reviews, and they need to slow down the pace of development so that code can be evaluated more rigorously before it is used by the millions. Users and customers, meanwhile, need to demand higher levels of security and overall software quality. They must also be willing to allow vendors to properly test code, rather than demanding the right to download the earliest “alpha,” “beta,” or “prerelease” program.

Java implementation errors

Most security flaws are implementation errors—bugs—that can simply be found and fixed. Working with the source code to the Java compiler and run-time environment, Dean and Wallach discovered many problems in the Java implementation.

There were three main classes of flaws:

  • Bugs with the Java virtual machine that let programs violate Java’s type system. Once the type system is violated, it is possible to convince the JVM to execute arbitrary machine code.

  • Class library bugs, which allow hostile programs to learn “private” information about the user or, in the case of Sun’s HotJava browser, edit the browser’s settings.

  • Fundamental design errors leading to web spoofing and other problems.

A complete list of the Princeton group’s findings is on the Web at http://www.cs.princeton.edu/sip/.

Most of the implementation errors discovered by the group were fixed shortly after they were reported.

Java design flaws

The Princeton Secure Internet Programming group has also identified numerous design flaws in the Java language itself. Design flaws are serious because fixing them can break legitimate programs that depend on the flaws for proper operation. Some design flaws cannot be fixed without fundamentally changing the underlying structure of the system.

The most serious design flaw with the Java system identified by the SIP group is that Java’s security model was never formally specified. Quoting from the literature of computer science, they repeated, “A program that has not been specified cannot be incorrect, it can only be surprising.” The group was forced to conclude that many of the apparent problems that they found weren’t necessarily security problems because no formal security model existed.

The second major problem with Java’s security is that the security of the entire system depends on maintaining the integrity of the Java type system. Maintaining that integrity depends on the absolute proper functioning of the SecurityManager class and the Bytecode Verifier. While the SecurityManager class is 500 lines long in the first set of Java implementations that were commercialized, the Bytecode Verifier was 3500 lines. To make things worse, there was no clear theory or reason as to what makes Java bytecode correct and what makes it incorrect, other than the operational definition that “valid bytecode is bytecode that passes the Bytecode Verifier.”

The SIP group has made several concrete suggestions for making Java a more secure environment in which to run programs. These recommendations include:

  • Public variables should not be writable across name spaces.

  • Java’s package mechanism should help enforce security policy.

  • Java’s bytecode should be simpler to check and formally verify. One way to do this would be to replace the current Java bytecode, which was designed to be small and portable but not designed to be formally verifiable, with a language that has the same semantics as the Java language itself. The SIP group proposes replacing or augmenting Java bytecode with abstract syntax trees.

Unfortunately, it’s not clear whether these underlying problems with the Java language are going to be addressed. Representatives from JavaSoft say they know that there are problems with the language, but there are already so many people using it that these problems may be impossible to fix.

The Java DNS policy dispute

One of the most interesting security problems discovered by the Princeton team boils down to a dispute with Sun regarding the policies of Sun’s Java sandbox implementation.

In February 1996, Felten et al. reported that they had discovered a security flaw in the Java run-time system: Java applets were vulnerable to DNS spoofing. The Princeton group suggested a workaround. But Sun said that Felten et al. were way off base. There was no such security flaw in Java, Sun said. The problem was with the Princeton researchers’ interpretation of Sun’s security policy.

Under Sun’s Java security policy for downloaded applets, a downloaded applet should only be able to initiate network connections to the same computer from which it was downloaded. But what is meant by the words “the same computer”?

According to Sun, “the same computer” means any computer that shares the same DNS name with the computer from which the applet was downloaded. Many computers on the Internet have more than one IP address for a single host name. Different IP addresses might be used for different interfaces. Alternatively, several computers may be given the same name because they are functioning as essentially the same computer using DNS round robin. (You might, for instance, have three web servers for a company, each with the same DNS name but each with its own IP address.)

Felten et al. showed that Sun’s definition of “the same computer” was open to DNS spoofing. If an attacker can convince the computer on which an applet is running that any arbitrary IP address has a particular DNS name, then that applet can open a connection to that IP address. This situation can be easily accomplished by someone running a rogue DNS server. Working together, the applet and the DNS server could enable the applet to initiate a connection to any computer on the Internet. For corporations with firewalls, this meant that an applet could probe for security weaknesses on systems that the corporation thought were protected.

Sun agreed that DNS spoofing is a problem, but said that the correct answer is to improve the security of the entire DNS system. Felten et al. agreed that DNS security should be improved but said that, until then, Java applets should run under a policy that permits them only to open network connections to the IP address from which they were downloaded, rather than the DNS name. Considering that problems with the DNS system have been known for many years and have still not been fixed, we think the Princeton team’s approach makes more sense.

Netscape ultimately issued a patch to Navigator that addressed the Princeton group’s concerns. Current Java implementations in Netscape Navigator are not susceptible to the DNS spoofing problem.

Another policy dispute that has not been settled is how much of the user’s personal information a Java applet should be able to access. Should a Java applet be able to determine the real name of the person who is running it? Should the Java applet be able to determine the person’s email address? Should it be able to send electronic mail on behalf of the user? Should the applet be able to find out what time it is? Unfortunately, it is probably not reasonable to expect users to decide these questions for themselves, because there may be profound security implications to these questions that are not at all obvious.

Java Security Future

Despite the problems discovered with Java, the good news is that the underlying design of the language makes it amenable to ultimately solving the security problem of downloaded programs.

One area where Java security can be enforced is in the run-time system, which can be used to enforce fine-grained control over security policy. For example, if an organization decided that Java applets shouldn’t be able to send electronic mail, the code could be configured to ensure that Java applets couldn’t open a TCP/IP connection to port 25, the SMTP port.[19]

One of the most important features that needs to be added to Java run-time systems is the logging of applet downloading and actions. The SIP group recommends logging all file system and network access as well as the applet bytecode itself. This allows attacks to be reconstructed and is probably necessary if one later wishes to seek legal recourse. Browser vendors may be thinking along these same lines: Internet Explorer 3.01 has a file named C:WINDOWSJAVA JAVALOG.TXT. Unfortunately, the file is merely a copy of the Java console and not an actual log of Java applets that are run. Internet Explorer 4.0 reportedly will have more sophisticated logging.

It’s also important to note that even though some Java implementations seem to have some security problems, this doesn’t mean that the alternatives (JavaScript, ActiveX, VBScript, and so forth) are secure. If anything, the research community has been focusing on Java attacks because Java’s creators claimed that it was designed with security in mind.

Currently, users who view security as a primary concern are well advised to disable the execution of Java programs by their browsers.



[13] Eric Greenberg of Netscape writes, “Jim Clark, Netscape’s founder, initially envisioned Mosaic as a product to be used within an interactive cable TV box for programming the programs you wanted to see. This was the first business model for Mosaic. Fortunately, the Mosaic team saw past this pipe dream and quickly focused on the Internet and the enterprise.” (Eric Greenberg, personal communication, March 22, 1997)

[14] C lets you do some interesting things. For instance, if you define char *p; int i; in a program, you can then use the terms p[i] and i[p] almost interchangeably in your code. Few C programmers understand the language well enough to understand quirks such as this.

[15] In technical terminology, programmers make errors that result in faults being present in the code. When the faults cause the code to produce results different from the specifications, that is a failure. Most casual users simply refer to all of these as “bugs,” and that’s why we do too.

[16] In fact, safety is an aid to people writing Trojan horses and hostile applications. Safety will help minimize the chances that a Trojan horse program will crash while it is reformatting your hard disk. Safety also helps ensure that the applet scanning your computer for confidential documents and surreptitiously mailing them to a remote site on the Internet won’t go into an infinite loop.

[17] However, the code could replicate itself and tie up processing resources, resulting in a denial of service.

[18] In Netscape Navigator, the java.lang.SecurityManager base class is subclassed by the netscape.lang.AppletSecurity class that implements the actual Java security policy.

[19] Reportedly, Finjan Software, based in Netanya, Israel, sells a product called SurfinBoard that addresses this kind of problem. The company can be reached at http://www.finjan.com. Finjan is Hebrew for a kind of coffee pot.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.134.77.195