Browse DevX
Sign up for e-mail newsletters from DevX


Check java.policy at Build Time to Avoid Runtime Errors : Page 2

Don't wait until runtime to discover that there's a syntax error in java.policy. Use a simple utility to check java.policy at build time to avoid unexpected runtime failures.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Activating the Security Manager
Before delving into the second critical configuration file, java.policy, I need to digress and point out that Java security isn't "turned on" by default. Java's security record is so remarkably good considering the ubiquity of Java code in the world today that many Java programmers don't know or realize this. The manager of all security operations in Java 2 is the SecurityManager class and by default this class is deactivated. You can engage the SecurityManager in one of two ways. First, you can specify it on the command line at runtime:

java –Djava.security.manager

Or you can programmatically activate it by instantiating a SecurityManager and calling it explicitly to perform the requisite security checks for your application.

Given the importance today of coding secure applications, Sun's choice to leave this disabled by default is unfortunate to say the least. If you don't turn on the Security Manager, java.policy isn't consulted at all and your application will never throw an AccessException. Given this gap in many developer's understanding of the Java security model it is certain that a lot of developers have been lulled into a false sense of security when in fact they have little or no security in place at all.

Setting Up Grant Blocks
Returning to the java.policy file, as mentioned previously, it is the second critical security configuration file in the default Java runtime environment and it is where permissions are configured. In Java, a Permission is configured in a grant block that is set up for a particular codebase. The first such grant in the default java.policy file provided by Sun is:

// Standard extensions get all permissions by default grant codeBase "file:${java.home}/lib/ext/*" { permission java.security.AllPermission; };

This grant allows any code installed in the /ext directory to have all permissions, literally. This is why fighting classpath problems by hoisting your code up the classloading delegation ladder into the /ext directory is so dangerous. Code living in this directory has rights to modify system properties and interact with the file system or do anything else you can think of on your system.

Note that Sun's 'codeBase' is specified as a URL and supports the asterisk ( * ) wildcard. If you neglect a quote, a curly brace, or the final semicolon (;) your Permission file won't be parsed and read properly at runtime (which is obviously why we're going to verify its format at build time).

All permissions specified in java.policy adhere to the same basic format but may have an additional action modifier appended to them such as in the following example.

// com.tillman.util.security.permissionchecker package is in this directory grant codeBase "file:/C:/eclipse/workspace/Permissions/PermissionReader/bin/*" { permission java.security.SecurityPermission "getPolicy"; permission java.io.FilePermission "<<ALL FILES>>", "read,write,execute,delete"; permission java.net.URLPermission "http://www.nytimes.com", "listen, connect"; };

The first permission in the block above is essential because the audit utility needs to get a reference to the Policy object in order to check its permissions so this must be explicitly permitted in the policy file. Obviously, you'll need to modify the file URL to point to where you've placed the audit utility.

The code that checks the permissions is fairly straightforward. The only twist I've put in is that I want to be able to specify the codebases to audit in a properties file. This gives me the flexibility to ignore the default Java grant blocks. (You'll note though that in the output these default blocks are appropriately added to the permissions that are of interest to me). The getFileLocations( ) method in the audit code simply returns a list of the codebases specified in my properties file (note the double backslashes to escape the backslash character on Windows).

From within a while loop, each of the locations specified in my properties file is converted to a codebase URL.

codebase = new File((String)iter.next()).toURL();

Each codebase is then passed as an argument to the CodeSource constructor. The CodeSource is effectively the "key" that the Policy object uses to retrieve the PermissionCollection.

cs = new CodeSource(codebase, null); pcoll = Policy.getPolicy().getPermissions(cs);

The PermissionCollection pcoll variable's members are returned as an enumeration using the elements( ) method. Finally, we iterate through the enumeration and use each retrieved Permission object's toString( ) method to print out its name.

enum1 = pcoll.elements(); for (; enum1.hasMoreElements(); ) { System.out.println((Object)enum1.nextElement()); }

The output displays something like this:

path: /C:/eclipse/workspace/Permissions/TestTwo/bin (java.util.PropertyPermission java.version read) (java.util.PropertyPermission java.vm.name read)

If the syntax of any of the permission grant blocks—or the permissions themselves—prove to be incorrect then the utility will display a message describing the parse error. In truth, the call to get the Policy object will blow up in this way without the rest of the code running. Nevertheless, the utility's listing of the aggregation of the permissions for each codebase will give you another opportunity to confirm that the security you're implementing is as desired.

Once you activate the SecurityManager the flexibility and power of the Java 2 security architecture is at your disposal. While the java.policy and java.security file formats would perhaps be better implemented as conventional XML files they are still fairly readable and manageable. Moreover, as you've seen, the java.policy file can be checked at build time to avoid unexpected runtime security lapses or failures. The Java Policy object can be extended to tailor its behavior to better meet your needs but the standard configuration options are adequate for most security needs.

Doug Tillman is a veteran Java and Python developer turned Scrum Master.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date