Read Latex

Tuesday, March 08, 2011

Trustworthy Java Applets Without Costly Certificates


Introduction
When you run a Java applet, the run time system looks for a file called java.policy, on your customer's system. This file specifies what rights Java will be granted at run time. If this file is not configured correctly your Java applet will not function properly and your customer will be frustrated. The only alternative to providing your customer a java.policy file is to buy a certificate that can cost over $500 per year. If your applet does not generate sufficient revenue to cover this, your voice is silenced along with your right to contribute. This also destroys the chance that your applet will be useful to someone a year from now, robbing you of future options as well.

So we would like to get useful applets running without permission problems while respecting the customer's right to security. We will accomplish this by establishing and maintaining a trust relationship with the customer as any supplier must do. In what follows the terms customer and user may be used interchangeably.

Applet Execution
Most applets are executed during development in interactive environments like NetBeans or Eclipse. For simplicity, an applet can be run in a browser, or as a standalone program, by you or your customer. Assuming Java is installed, an applet can be run in a browser simply by visiting a web page that hosts it. It can also be run in standalone mode by typing:


at a command prompt. Getting the right prompt is critical, otherwise hidden errors can disguise what Java is really doing. Getting the right prompt will be covered below. The term right prompt is a useful misnomer. It is really the environment behind the prompt that must be checked, but we want to make a complex thing simple, so we pretend it is a single character, keyword, or phrase, like mathematicians do.

Running appletviewer is useful for testing security fixes. Why? Because you can run it with test java.policy files like so:



Notice there is no space between the -J and the -D in the statement above.

A useful java.policy file for development and testing is:

                     


Blanket permission is not safe for production settings. You can stop here, develop the most sophisticated applet you want, and then resume to deploy your applet. We will now cover four remaining issues to understand and solve Java applet security problems. These issues are:
  1. Getting system properties such as ${user.home}
  2. Getting the right prompt for Windows and Unix systems.
  3. Testing an appropriate java.policy file.
  4. Deploying a java.policy file.
1. Getting System Properties
Some users and most developers have several versions of Java installed. In this situation the value of key system properties can depend on what you are doing. Continuing our java.policy thread, we need to know the exact directory to which ${user.home} refers. To replace complex speculation with simple fact, we run the program PrintUserHome.java:


to produce the output:


Authors note: 
In the text below, please assume that any word that starts with an upper case letter is a trademark held by their respective owners.

Many Java developers use Interactive Development Environments (IDE's) such as Netbeans or Eclipse. Compiling and running tiny programs in these can be a hassle.  This hassle can be eliminated by running programs in Unix environments, like MacOS/Linux, or in  cygwin, a wonderful Unix platform which sits atop Windows. In any of these a tiny Java program can be run without an IDE, without ant or make using the policyInstaller available at the end of this document. In the java.policy file above, we give the Java Runtime Environment (JRE) permission to read files from ${user.home}. This directory becomes the "sandbox" for those activities our grant permission directive allowed. Other key system properties can be listed using similar calls to those above. These are also enumerated in the policyInstaller:




2. Getting 'The Right Prompt'
We can inspect other key system properties by typing:

$ set | grep "JAVA|CLASSPATH"



On the same machine we can open a command "Window" and repeat using a variant of the same command:

$ set | grep "JAVA\|CLASSPATH"



Here we notice an important discrepancy, that the value of JAVA_HOME is different.
It is
...\jdk1.6.0_22 in the first case and ...\jdk1.6.0_10 in the other.

If we were to place an applet policy file in the wrong JAVA_HOME location, it would not work, and we might not know why. If that was done both the customer and the developer would be frustrated. Not good!

This can be fixed by editing the windows environment variables, which require a reboot of the system to take effect. To access these, right-click the mouse and select:
My Computer-->Properties-->Advanced-->Environment Variables.
Then examine the System variables.



In this case we would change the JDK version suffix from 10 to a 22 as shown and reboot.

When these two environments are consistent we have the 'right prompt'. More formal developments can be found at the references provided.

3. Testing an appropriate java.policy File

The blanket permission we granted above for testing and development is not appropriate for applet deployment. Instead we run the applet together with the java.policy file in the local directory granting the most restricted possible permissions until security exceptions no longer occur. As before this is done using appletviewer with the options shown below:


Each a time an exception occurs, we can add a line to the java.policy file that grants permission for that specific exception, using the text of the exception itself as a guide.


The java.policy file above restricts File I/O to the directory Java calls ${user.home}.
The wildcard character '*' says that any file or directory in ${user.home} may be read or written. One could add the keywords write,delete or  execute to this permission directive. Additional keywords are separated by commas, i.e.: "read, write, execute", etc. The references titled "Appendix A..." below provides a complete description of all the possible permission directives. For example, in the applet that motivated this blog entry, the final java.policy file looked like this by the time it ran without exception.


After we have successfully tested the applet using a candidate java.policy file we are ready to deploy both the applet and policy files.


4. Deploying an java.policy File.

Local Deployment
We first deploy the java.policy file locally to the directory in which we were running the applet. . Then we test the applet again using applet viewer.

Now we have a compatible applet.html and java.policy combination. The applet.html can be deployed either as a proprietary custom solution for desktop use, or as a traditional web page for widespread use. We will cover the later case. Since a correct java.policy file is required for execution of many applets, the file itself, properly installed constitutes an informal key enabling the software to function. Note that whenever the user upgrades their version of Java, a new java.policy file must be deployed to the correct location.


There are two ways to deploy the java.policy file. One is to let the user download and install it themselves, but this requires expertise and patience some customers may not have (regrettably). Another way is to bundle the file in the policyInstaller below which the customer downloads and executes to install the java.policy file. It is good practice to inform the customer of the risks that installing the policy file may entail. This can be part of the EULA that the installer requires the customer to agree to, or placed on the web page from which the policy file is downloaded.


Location of the java.policy file.
For an applet to run on a user's machine the java.policy file must be installed in this location:

${user.home}\.java.policy

Policy Installer
A zip file containing the policyInstaller, source code, directory structure, and setup instructions for the IDE-less Java examples is available by sending $19.99 via PayPal to the author's email address. The zip file describes how to quickly and easily make a simple jar file and manifest for testing java.policy  files and IDE-less java execution.

References:
  1. Appendix A: Security and Permissions, Oracle Document
  2. How do I get user home directory name?, Kodejava Example
  3. Hello World without an IDE.