Platform-independent browser security in Java

Don McGregor
(mcgredo@mbay.net)

This security package implements a way to do platform-independent code that breaks out of the Java sandbox to perform filesystem access, network access, or Java properties database access. It's part of a larger project I'm working on, but I broke it out here because it seems generally useful.

This is closely modeled on Greg Frascadore's system outlined in the May, 1999 issue of Java Pro magazine. An abstract superclass, SecurityStrategy, has subclasses for the major security models: Netscape, Microsoft, and Sun. At runtime the correct strategy is instantiated and returned. Note that this system, as implemented, is intended to more bypass security than to properly limit access. For example, classes and interfaces in the security package are declared public, wich means that any class outside this package can use these classes to bypass the sandbox.

If there were no security in Java, you'd be able to do something like this:

  myObject.methodThatAccessesFiles(arg1, arg2, arg3, arg4);

The security models will prohibit this if running in a web browser, however. There are of course ways around this, but the problem is that there are at least three ways around the problem, only one of which works on a given platform. So I've included security models for the three major platforms that encapsulate the security models and methods that must be called for each platform. Unfortuantely, I can't make this entirely transparent in the code. What you have to do, when invoking a method that requires access outside the sandbox, is to first call the security manager. The security manager in turn calls the object with the method, after turning on all the neccessary access rights. In practice, it looks something like this:

    Object argArray[] = {arg1, arg2, arg3, arg4};

    securityManager.invoke(myObject, "methodThatAccessesFiles", argArray);

The object that wants access outside the sandbox is passed in, along with the name of the method in which access is required, and an array of all the arguments. The securityManager instance does all the right security calls for the platform it's running on, then does a java reflection lookup of the method in the class, and dynamically invokes the method with the argument list.

There are two gotchas here. The first is that you lose compile-time checking for the existence of the method. If the object does not implement "methodThatAccessesFiles" you won't find out about it until runtime. Oh well; strong typing is for weak minds. The second problem is that all the arguments to the method must be first-class objects. You can't pass in Java primitive types such as int, double, or boolean.

A class that wants access outside the sandbox must implement a marker badge--an interface that has no methods. Right now three kinds of access outside the sandbox are allowed: filesystem access, network access, and access to the Java properties database. You'd declare a class that needed access to the network like this:

class IWantNetworks implements NetworkCommBadge

The interface "NetworkCommBadge" implements no methods; it is just a marker interface, and its presense or absence is all we're worred about. A class passed in that did not implement the NetworkCommBadge would result in a compile-time error.

A simple example of the security package's use is shown in the TestApplet program in the org/web3d/vrtp/security directory.

Compiling this code can be slightly tricky. To compile all the classes in the directory, see compiling.html

If you don't want some platform's security model, just delete it.