Security Management with Java 2
In this article we show you how to apply the security features of Java 2 to applets and applications running on your system.
Applying a Security Manager to Applets and Applications
The security manager is invoked by all the Java system code to perform access control checks based on the security policy currently in effect. A security manager (an implementation of the class SecurityManager) is typically installed when an applet is running (the Applet Viewer and most of the browsers install a security manager). A security manager is, however, not automatically installed when an application is running. To apply the same security policy to an application as is implemented by the security manager for an applet, there are two options available:
1. While running the application, the java command line option –Djava.security.manager should be provided. For instance, the JVM would invoke the security manager to apply the security policy to the application HelloWorld with the following command:
java -Djava.security.manager HelloWorld
Notice that the command line option -Djava.security.manager is a new flag introduced with Java 2 SDK, Standard Edition, V1.2. An application did not run under a security manager in JDK 1.0 or 1.1, since local code was considered trusted by default.
A variant of the option above allows the user to specify a customized security manager, say the class MySecurityManager. In this case the syntax is the following:
java -Djava.security.manager=MySecurityManager HelloWorld The default built-in security manager can be invoked by any of the following commands which are equivalent:
java -Djava.security.manager HelloWorld java -Djava.security.manager="" HelloWorld java -Djava.security.manager=default HelloWorld
2. The application itself can call the setSecurityManager() method in the java.lang.System class. Examples of how to use the setSecurityManager() method.
Applying a User-Defined Security Policy
It is also possible to apply a user-defined security policy file in addition to or different from the security policy files specified in the security properties file java.security. This can be done by using the -Djava.security.policy command
line argument. A command like:
java -Djava.security.manager -Djava.security.policy=MyPolicy HelloWorld
means that the security policy file MyPolicy will be used in addition to all the policy files specified in the security properties file. A command like:
java -Djava.security.manager -Djava.security.policy==MyPolicy HelloWorld
means that only the security policy file MyPolicy will be used and all others will be ignored.
Notice that the java command line option -Djava.security.policy allows you to specify the URL of MyPolicy, so that even remote policy files can be passed on to the command line.
Java Security Debugging
Security access can be monitored by setting the java.security.debug system property. A list of all debugging options can be viewed by typing:
java -Djava.security.debug=help
The following screen shows the results of typing the command above:
We want to show now a concrete example of security debugging. Consider the following Java application:
SomeProperties.java
The program above can be compiled by simply issuing the command:
javac SomeProperties.java
You can then run the Java class SomeProperties by launching:
java SomeProperties
The output produced is shown in the following screen:
The program SomeProperties displays the value of the properties sun.boot.class.path and user.home. It also attempts to print the value of the property java.sys.class.path, which was the variable used with beta versions of Java 2 SDK, Standard Edition, V1.2 to indicate the system class path. That variable was then deprecated in the GA version of Java 2 SDK, Standard Edition, V1.2, and replaced by sun.boot.class.path. Hence, the value of java.sys.class.path is displayed as null in the output screen above.
Notice that the program above will not work with the option -Djava.security.manager ; it will throw an AccessControlException, unless it is granted in one of the current policy files the permission to read system properties. This can be done by adding the following lines to one of the policy files currently in use:
where file:/D:/itso/ch03/ is the URL of the directory where SomeProperties.class is installed.
Notice that permission to read the system property java.sys.class.path must be granted although this system property does not exist, because the system attempts to read it anyway; otherwise, an AccessControlException will be thrown, as shown:
The following command, launched from the directory D:\itso\ch03 where the SomeProperties class file resides, shows how it is possible to perform full security debugging:
java -Djava.security.debug=all SomeProperties > Output.txt 2> SecurityDebug.txt
Launching this command will cause two text files to be created: Output.txt, which will contain the normal output of the program as shown, and SecurityDebug.txt, which is the file containing all the security debugging information. We show the contents of SecurityDebug.txt in the two following:
Figure . Security Debug Information
Figure. Security Debug Information
Figure . Security Debug Information
As you can see, due to the -Djava.security.debug=all option given during the run-time command, an entire step-by-step security debug history is produced. This output would be printed on the screen if we had not redirected it to the SecurityDebug.txt file.
The first step the system performs when running a program is to load classes. The classes in the system class path are first loaded without checking for their protection domains since these classes are shipped with the JVM and are supposed to be trusted. Next, in the sequence of class loading, are the classes in the extensions directories, specified by the java.ext.dirs system variable. Finally the classes specified by the value of java.class.path, which gives the application class path, are loaded.
These classes have to be assigned to their protection domains. Hence the getPermissions() method of SecureClassLoader is invoked. The argument passed to the getPermissions() method is the code source of the SomeProperties class.
In general, the getPermissions() method returns an object of type PermissionCollection, which is a list of all the permissions given to the code source supplied as argument to getPermissions(). To get the PermissionCollection object, the security policy files that specify the permissions to be granted to a given code source are examined. The security properties file used in this example is the same default properties file java.security that comes with the installation of the Java 2 SDK. The locations of the policy files in the preference order it gives are:
policy.url.1=file:${java.home}/lib/security/java.policy policy.url.2=file:${user.home}/.java.policy
The policy file located at file:${java.home}/lib/security/java.policy is accessed first. Then the policy file specified at file:${user.home}/.java.policy is accessed. The second file, .java.policy, is a user-defined policy file, which can be written by the user to specify more information on permissions. Note that it is not installed by default; rather, users must create it explicitly.
In this case, the file has not been explicitly created. Therefore in the debug history, we see that the file ${user.home}/.java.policy is not found during run-time. Once the security policy file has been found, the permissions granted for different code sources are evaluated. The protection domain for the classes in the extensions directories and application class path are assigned, then the final set of permissions for those classes are listed.
The program is executed successfully because the classes in the application class path (which is the current directory D:\itso\ch03) have the permissions to access all the resources required to execute the program.