Limiting file access in Java

obfuscation picture obfuscation · Apr 2, 2011 · Viewed 9k times · Source

Problem:
In my Java application (not an applet) I wish to limit certain file operations to all classes except a list/group/package of classes that should not be restricted.

Specifically, I would like to limit...

  • File reads
  • File writes
  • File creation
  • File deletion

...such that they can only be done within the current working directory for all but the unrestricted classes.

SecurityManager attempt:
I have tried to implement a subclass of the SecurityManager class that implements this behaviour, however it seems that when checks are made the file information provided does not give more than just the filename (unless I am missing something?).

Also, I don't quite understand how in this case I could find out the class which the call is being made from, to allow me to determine whether to allow the operation or throw an exception. Is there any way I could get all the information I need for this approach to work?

Policy-based attempt:
I am also aware that Java policies are intended for restricting the actions of classes, including things such as file operations. However, I've really struggled to find a good resource to learn how I could go about solving my problems using a .policy file.

Summarisation of question:

1) Are there any alternative approaches that may be preferable to those I've mentioned?

2) Is this possible using a SecurityManager? Am I missing out on how I should actually be implementing such an approach?

3) Is this possible using a policy file? Are there any good resources I've missed on this front?

I'm really not adversed to any amount of hard work I need to invest in achieving this- I'm just unsure as to how I should approach it properly. I'm also sorely lacking in good resources to teach me enough about the two possible approaches I've mentioned, to allow me to implement it myself. Above all, I'm not afraid of significant reading where required!

Thanks for any help you can give, in advance.

Answer

Simon G. picture Simon G. · Apr 3, 2011

Here is how you can do it using a policy file.

Create a Java file that can act with privileges:

package egPriv;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

public class PrivCat {
    /** Cat a file with no privileges */
    public void cat(String file) throws IOException {
        cat(new FileReader(file));
    }

    private void cat(Reader r) throws IOException {
        int c;
        while( (c = r.read()) != -1 ) {
            System.out.print((char) c);
        }
        r.close();
    }

    /** Cat a file WITH privileges */
    public void catPriv(final String file) throws IOException {
        Reader r;
        try {
            r = AccessController.doPrivileged(new PrivilegedExceptionAction<Reader>() {
                public Reader run() throws IOException {
                    return new FileReader(file);
                }
            });
        } catch (PrivilegedActionException e) {
            throw (IOException) e.getCause();
        }
        cat(r);
    }
}

Create a regular file for demonstating

package eg;

import egPriv.PrivCat;

import java.io.IOException;

public class Cat extends PrivCat {
    public static void main(String[] args) throws IOException {
        Cat eg2 = new Cat();
        System.out.println("Processing with privilege:");
        eg2.catPriv(args[0]);

        System.out.println("Processing normally");
        eg2.cat(args[0]);
    }
}

Create sample.policy file:

/* anyone can read write and execute within current working dir */
grant {
  permission java.io.FilePermission "${user.dir}", "read,write,execute";
};

grant {
  permission java.io.FilePermission "${user.dir}/*", "read,write,execute,delete";
};


/* Only code from this jar can work outside of CWD */
grant codebase "file:egPriv.jar" {
  permission java.io.FilePermission "<<ALL FILES>>", "read,write,execute,delete";
};

Compile and then Test:

jar cvf egPriv.jar egPriv
jar cvf eg.jar eg


echo 'Restricted' > ..\file.txt
java -cp eg.jar;egPriv.jar -Djava.security.manager -Djava.security.policy=sample.policy  eg.Cat ..\file.txt

echo 'Open' > file.txt
java -cp eg.jar;egPriv.jar -Djava.security.manager -Djava.security.policy=sample.policy  eg.Cat file.txt