Chapter 4. Applet Security

Applet security is a major concern among Web users and applet developers. From a user's perspective, an exploitable applet security flaw can result in sensitive data being modified or disclosed or a computer being rendered inoperable. From a developer's perspective, strong applet security is necessary to make Web users comfortable with applets. However, too high a level of security limits an applet's capabilities.

The Java 2 security model meets both user and developer needs. It enables users to maintain high levels of security, by default, and also to relax these security controls to take advantage of additional applet capabilities that are provided by trusted developers.

In this chapter, you'll learn how to use the Java 2 security model to develop applets that extend the bounds of the applet sandbox and use previously restricted capabilities. You'll cover the issues involved with specifying an applet security policy and the use of signed applets in a more flexible security policy. You'll then investigate the use of the jar and jarsigner tools in the packaging and signing of applets in terms of JAR files. Next, you will study issues involved with signing certificates and learn how to sign applets for use with both Internet Explorer and Netscape Navigator.

Extending the Sandbox

One of the most appealing features of Java in its debut as a Web programming language was the comprehensive security built into the Java runtime environment. The Java sandbox provided a mechanism for untrusted code to be downloaded from the Web and executed in a secure manner. The sandboxes of JDK 1.0 and 1.1 had some holes, but Sun encouraged the Internet community to find those holes and then quickly fixed them. The security model implemented by the Java sandbox has been strengthened and, at the same time, made more flexible from JDK 1.0 to JDK 1.2. In addition, JDK 1.2 provides a number of security mechanisms that can be used within the sandbox. One of the most powerful security features introduced in JDK 1.2 is the capability to specify a security policy for applets and applications. This feature gives software developers a great deal of flexibility in functionality that they can incorporate into their applets and applications. At the same time, it provides users with total control over the access they allow to these programs. The configurable security policy of JDK 1.2 enables Java software developers to provide the capabilities their users want, and it enables users to limit those capabilities based on their degree of trust in the source of the Java software they execute.

The JDK 1.0 Sandbox

To understand how the configurable security policy works and why it is useful, it is helpful to trace the evolution of Java security. JDK 1.0 introduced the sandbox approach to applet security. In this approach, all standalone Java applications are trusted by default and are allowed unrestricted access to your system resources (file system, network, and other programs). Applets that are loaded over the network are, by default, untrusted and prevented from accessing your local file system and other programs. In addition, applets are only allowed to make network connections to the host from which they are loaded.

The objective of the JDK 1.0 sandbox was to protect users from malicious applets downloaded from the Web. As I mentioned earlier, with the exception of a few security holes (which were subsequently corrected) the JDK 1.0 sandbox met this objective. However, in blocking potentially hostile applet accesses, the 1.0 sandbox also removed useful applet capabilities.

For an example of the security provided by the JDK 1.0 sandbox, consider the applet shown in Listing 4.1 and referenced in Listing 4.2. This applet reads the file specified in an applet's fileName parameter and displays the file's contents in a TextArea object. (If a security exception occurs, it is displayed in the TextArea object instead.) When you view the applet using Microsoft Internet Explorer 5.0, you receive the security exception shown in Figure 4.1.

A security exception is thrown when an applet tries to go outside of the sandbox.

Figure 4.1. A security exception is thrown when an applet tries to go outside of the sandbox.

Example 4.1. The ReadFileApplet

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class ReadFileApplet extends Applet {
 TextArea text = new TextArea();
 Button goButton = new Button("Read Local File");
 Panel panel = new Panel();
 String fileName = "";
 public void init() {
  fileName = getParameter("fileName");
  setLayout(new BorderLayout());
  goButton.addActionListener(new ButtonHandler());
  panel.add(goButton);
  add("North",panel);
  add("Center",text);
 }
 class ButtonHandler implements ActionListener {
  public void actionPerformed(ActionEvent e){
   String s = e.getActionCommand();
   if("Read Local File".equals(s)){
    try {
     FileInputStream inStream = new FileInputStream(fileName);
     int inBytes = inStream.available();
     byte inBuf[] = new byte[inBytes];
     int bytesRead = inStream.read(inBuf,0,inBytes);
     text.setText(new String(inBuf));
    }catch(Exception ex){
      text.setText (ex.toString());
    }
   }
  }
 }
}

Example 4.2. The ReadFileApplet.htm File

<HTML>
<HEAD>
<TITLE>An Applet that reads local files</TITLE>
</HEAD>
<BODY>
<H1>An Applet that reads local files.</H1>
<APPLET CODE="ReadFileApplet.class" HEIGHT=300 WIDTH=600>
<PARAM NAME="fileName" VALUE="C:AUTOEXEC.BAT">
Text displayed by browsers that are not Java-enabled.
</APPLET>
</BODY>
</HTML>

The JDK 1.1 Sandbox

The JDK 1.1 sandbox was designed to maintain the security of the JDK 1.0 approach while allowing certain applets to be designated as trusted. Trusted applets are allowed to perform accesses that exceed the bounds of the sandbox. The Security API of JDK 1.1 provides the capability to digitally sign an applet and then verify that signature before an applet is loaded and executed. This capability enables browsers to authenticate that an applet is signed by a trusted party and that it has not been modified since the time of its signature. Given this additional level of security assurance, signed applets are considered to be as trustworthy as (or even more trustworthy than) standalone application programs.

When I configure Internet Explorer 5.0 to trust my Web site (http://www.jaworski.com) and to allow applets from trusted hosts to access local files, I can execute the ReadFileApplet in Listing 4.1, and have it read and display the contents of my AUTOEXEC.BAT file, as shown in Figure 4.2.

JDK 1.1 security allows trusted applets to go outside of the sandbox.

Figure 4.2. JDK 1.1 security allows trusted applets to go outside of the sandbox.

The JDK 1.1 security approach is a significant improvement on the JDK 1.0 approach because it enables applet designers to add useful capabilities such as reading from and writing to the local file system, launching programs, and advanced networking. The shortcomings of the JDK 1.1 sandbox stem from its bipolar approach to security—an applet is either untrusted and confined to the sandbox, or it is trusted and given unrestricted access outside the sandbox. Applications are always trusted and given unrestricted access.

The problem with the JDK 1.1 approach is that it violates the security principle of least privilege. This principle states that an application should be given only those privileges that it needs to carry out its function and no more. According to least privilege, trusted applets and applications should be limited in the privileges they are allowed. For example, now that Internet Explorer 5.0 is reconfigured to run the ReadFileApplet, it will allow all applets from http://www.jaworski.com full access to my local file system. If Internet Explorer 5.0 implemented least privilege, I would be able to select the applets from http://www.jaworski.com that would have the privilege of accessing my local files.

JDK 1.2 Least Privilege

JDK 1.2 introduces a security architecture for implementing least privilege. This architecture is based on the capability to specify a security policy that determines what accesses an applet or application is allowed based on its source and on the identities of those who have signed the applet on application code.

The security policy feature of JDK 1.2 enables you to specify the following types of policies easily and without programming:

  • Grant all applets from http://www.trusted.com/ permission to read files in the C: mp directory.

  • Grant all applets (from any host) permission to listen on TCP ports greater than 1023.

  • Grant all applets signed by Mary and Ted (hypothetical Java programmers) that are from http://www.trusted.com permission to read and write to files in the C: mp directory.

  • Grant all applications loaded from the C: rusted directory permission to set security properties.

The next section shows how to specify the details of a particular security policy.

Specifying an Applet Security Policy

Specifying a custom security policy is easy to do. All you have to do is edit the appropriate policy configuration file. JDK 1.2 provides you with a number of ways to do this:

  • You can create or edit the default system policy file located at <java.home>libsecurityjava.policy, where <java.home> identifies the location of your JDK 1.2 installation. It is specified by the value of the java.home system property. By default, java.home is C:jdk1.2.2jre. If you edit java.policy, the new policy will apply to all users of your JDK 1.2 installation.

  • You can set the value of the policy.java system property to the name of an alternative security policy file.

  • You can create or edit the user policy file located at <user.home>.java.policy, where <user.home> identifies the current user's home directory. It is specified by the value of the user.home system property.

  • You can set the value of the java.policy property to a different user security policy file using the -D command-line option. For example, suppose that you want to run the Test class using the test.policy user security policy file. You could use the -D option as follows:

    java -Djava.policy="test.policy" Test
    
  • You can change the class used to implement the security policy from java.security.PolicyFile to another class by editing the java.security file located at <java.home>libsecurityjava.security. Change the line

    policy.provider=java.security.PolicyFile
    

    to

    policy.provider=OtherClass
    							

    where OtherClass is the fully qualified name of the class to be used.

When the Java byte code interpreter is run, it loads in the system policy followed by the user policy. If neither of these policies is available, the original sandbox policy is used.

The Contents of the Security Policy File

The policy file (system or user) consists of a series of statements, referred to as grant entries, that identify the permissions granted to code (applet or application) based on both the location from which it is loaded and on any signers of the code.

Note

In JDK 1.2, all code, whether it is an applet that is loaded from a remote host or an application from the local file system, is associated with a code source. This code source is defined by the URL from which the code is loaded and a list of signers of the code. These signers are identified by the names associated with the signers'public keys. These names are referred to as aliases. The aliases and keys are stored in a user's keystore, as described in Chapter 6,"Key Management and Digital Certificates."

The grant entries of the security policy identify a code source (URL and list of signers), followed by the permissions granted to that code source. The permissions (also referred to as permission entries) specify the actions that a code source can take with respect to a protected resource. If all this seems too abstract, hang in there. After I cover the syntax of grant entries and provide a few examples, the process of setting up a security policy will appear quite simple.

The Syntax of Grant Entries

Grant entries begin with the keyword grant, followed by optional SignedBy or CodeBase clauses, followed by an opening bracket ({), followed by a list of permission entries, followed by a closing bracket (}) and a semicolon. The syntax of a grant entry follows:

grant [SignedBy "signer_names"] [, CodeBase "URL"] {
  permission entries
};

The SignedBy clause contains a comma-separated list of the aliases of the signers of the code to which the grant entry applies. If the code has not been signed or the signers don't factor into the policy, the SignedBy clause can be omitted. Examples of SignedBy clauses follow:

SignedBy "Bill"
SignedBy "Bill,Ted"
SignedBy "Bill,Ted,Alice"

The aliases are not case sensitive. For example, "Bill" and "bill" are equivalent.

The CodeBase clause identifies the URL of the location from which the code is loaded.

Examples follow:

CodeBase "http://www.trusted.com"
CodeBase "http://www.trusted.com/omega/version5/"
CodeBase "file:/local/applets/"

The first example specifies that the grant entry applies to all code that is loaded from http://www.trusted.com. The second example specifies that the grant entry applies to all code that is loaded from /omega/version5/ (and all subdirectories) of http://www.trusted.com. The third example specifies that the grant entry applies to all code that is loaded from the localapplets directory (and all subdirectories) of the local file system.

If the CodeBase clause is omitted, the grant entry applies to all code locations. Note that syntactically the CodeBase clause might appear before the SignedBy clause. If both clauses are present, they are separated by a comma.

Using Signed Applets

By signing an applet, an organization (or individual) can indicate that the organization has reviewed the applet for security and believes that the signed applet is free from security defects. The signature also implies that the organization takes responsibility for the applet in cases where there is a security malfunction. Signing also provides the user with a mechanism for verifying that a signed applet originates from a particular organization and has been delivered to the user without modification. For these reasons, a user can determine that he or she is able to extend a certain level of trust to an applet that is signed by a reputable organization.

An applet is signed in two steps. In the first step, the applet's class files are archived in a JAR file using the jar tool. In the second step, the jarsigner tool is used to sign the JAR file. The result is a signed JAR file that can be used to distribute the signed applet.

Appendix G,"Using thejarsigner Tool," covers the use of the jar and jarsigner tools. However, I'll provide you with a quick example of their operation in the following sections. I'll archive and sign the ReadFileApplet of Listing 4.1.

Creating the JAR file

To create a JAR file named rf.jar that contains the ReadFileApplet.class and ReadFileApplet$ButtonHandler.class files, go to the directory where these files reside and execute the following command:

jar -cf rf.jar *.class

This adds both of the .class files to the rf.jar archive. You can then verify the archive file by listing its contents:

jar -tf rf.jar
META-INF/
META-INF/MANIFEST.MF
ReadFileApplet$ButtonHandler.class
ReadFileApplet.class

The META-INF directory and MANIFEST.MF file are created by the jar tool.

To use rf.jar, you must modify ReadFileApplet.htm to include the ARCHIVE="rf.jar" attribute in the APPLET tag as shown in Listing 4.3.

Example 4.3. Using the ARCHIVE Attribute of the APPLET Tag

<HTML>
<HEAD>
<TITLE>An Applet that reads local files</TITLE>
</HEAD>
<BODY>
<H1>An Applet that reads local files.</H1>
<APPLET CODE="ReadFileApplet.class" ARCHIVE="rf.jar" HEIGHT=300 WIDTH=600>
<PARAM NAME="fileName" VALUE="C:AUTOEXEC.BAT">
Text displayed by browsers that are not Java-enabled.
</APPLET>
</BODY>
</HTML>

Signing the JAR File

The rf.jar file won't be useful unless I sign it. This is easily accomplished using jarsigner. However, it requires me to generate a keystore as described in Chapter 6.

Suppose that I have a keystore named MyStore, with password MyPassword, and alias Me. I can sign rf.jar using the private key of Me as follows:

jarsigner -keystore MyStore -storepass MyPassword -keypass MyPassword rf.jar Me

The rf.jar file is updated as follows:

  • A signature (.SF) file is added to the META-INF directory. The name of this signature file is the first eight characters of the alias used to sign the file. This name can be changed using the -sigFile option.

  • A signature block (.DSA) file is added to the META-INF directory. The name of the signature block file is generated in the same way as the signature file.

The signature file identifies each file in the JAR file, the digest algorithm used in the signing process, and a digest value. The digest value is the digest computed from the file's entry in the manifest file.

The signature block file contains the signature of the signature file and a certificate that authenticates the public key corresponding to the private key used in the signature generation. The signature block file is a binary file.

Note

A JAR file may have multiple signers. Each signer signs the JAR file in succession.

Specifying a Signed Applet Policy

Now that you've signed rf.jar, update your policy to give the signed applet additional privileges. I edited my jre/lib/security/java.policy file to give files signed by me the following permission:

permission java.io.FilePermission "C:\AUTOEXEC.BAT", "read";

When I ran ReadFileApplet.htm using appletviewer it was able to read my AUTOEXEC.BAT file as shown in Figure 4.3.

Reading AUTOEXEC.BAT from an applet.

Figure 4.3. Reading AUTOEXEC.BAT from an applet.

Obtaining a Signing Certificate

In order to sign JAR files for use with Internet Explorer and Navigator, you'll have to obtain a signing certificate from a certificate authority (CA). Because of incompatibilities between Internet Explorer and Navigator, you'll need a separate certificate for each browser. If you get your certificate from a big name CA, such as Verisign (http://www.verisign.com), you can expect to pay a steep price (approximately $1000). You can save quite a bit of money by getting your certificates from lesser-known CAs, such as Thawte (http://www.thawte.com; approximately $250). Because both Internet Explorer and Navigator support Thawte certificates, a Thawte certificate is just as good as a Verisign certificate.

Working with Different Browsers

After you obtain your browser-specific signing certificates, you'll want to obtain the latest documentation on Navigator's and Internet Explorer's signing APIs. Because versions 4 and 5 of these browsers do not directly support the Java 2 API, you'll have to deal with browser-specific extensions to the JDK 1.1 API in order to make your signed applets work with these browsers. Another alternative is to use the Java plug-in, which supports Java 2 and will reduce the problems of having to deal with browser-specific APIs.

Summary

In this chapter, you looked at the security mechanisms used by the JRE from the point of view of the applet developer and learned how applet security policies can be tailored by users to allow more trusted applets to have additional privileges when they are executed in the user's browser.

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

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