Friday, April 16, 2010

Java Security Model

An OS process runs under the privileges of the user who fork the process. Therefore under normal conditions a java applications also runs under the privileges of the user who starts it. But there are situations where some privileges of the person who starts it should not be granted to the java application and only set of java code should give the privilege access.
Java security model provides a solution for this problem. It let users to specify a set of granted permissions and act as a additional security layer between java application and OS allowing only granted permissions.
To understand the concepts lets use the following sample program which creates the file test/test.txt.
public class CreateFile {
public void createFile(){
File file = new File("test/test.txt");
try {
System.out.println("Creating file ==> " + file.getAbsolutePath());
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new CreateFile().createFile();
}
}
Now lets run the program with the following command as a normal user
java -classpath classes/ com.test.security.CreateFile

This would create the file without any problem in the test directory. Here we ran this program without the security manager. Now lets try to run this program as super user but with the security manager.

java -Djava.security.manager -classpath classes/ com.test.security.CreateFile
Exception in thread "main" java.security.AccessControlException: access denied (java.util.PropertyPermission user.dir read)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
at java.security.AccessController.checkPermission(AccessController.java:427)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1285)
at java.lang.System.getProperty(System.java:628)
at java.io.UnixFileSystem.resolve(UnixFileSystem.java:118)
at java.io.File.getAbsolutePath(File.java:473)
at com.test.security.CreateFile.createFile(CreateFile.java:27)
at com.test.security.CreateFile.main(CreateFile.java:35)

So Even this simple operation runs as the super user it is not allowed to create the file. When a program runs under the security manager it only exposes the security permissions allowed in the security policy files. This is similar to Linux Capabilities. In this way only the required security permission can be given even the program has to started as super users.
Now lets give the necessary permissions to run this program.
First lets create the policy file as follows
grant {
permission java.util.PropertyPermission "user.dir", "read";
permission java.io.FilePermission "test/test.txt", "write";
};

And now run this program as follows,
java -Djava.security.manager -Djava.security.policy=policy/sample.policy -classpath classes/ com.test.security.CreateFile

Here the -Djava.security.policy is used to specify the policy file location. Now again file is created successfully.

To understand what happens exactly lets implements our own security permission. Here we write a watch tv permission.
public class TVPermission extends BasicPermission {
public TVPermission(String name) {
super(name);
}
public TVPermission(String name, String actions) {
super(name, actions);
}
public boolean implies(Permission p) {
boolean isPermitted = false;
if (p instanceof TVPermission){
isPermitted = p.getName().equals(getName())
&& p.getActions().equals(getActions());
}
return isPermitted;
}
}

Any java permission should implements the java.security.Permission interface. Implies is the important method. Actually when someone requests a permission normally java creates a permission object for that object and check for the permission. Lets use this code to check this.

public class WatchTV {
public void watchTV() {
TVPermission tvPermission = new TVPermission("chanel-5", "watch");
AccessController.checkPermission(tvPermission);
// other code goes here
}
public static void main(String[] args) {
new WatchTV().watchTV();
}
}

Now run this program with the following command
It gives this exception
Exception in thread "main" java.security.AccessControlException: access denied (com.test.permission.TVPermission chanel-5)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
at java.security.AccessController.checkPermission(AccessController.java:427)
at com.test.security.WatchTV.watchTV(WatchTV.java:27)
at com.test.security.WatchTV.main(WatchTV.java:32)

Now lets add this permission to the policy file as follows and run with the policy file.
grant {
permission java.util.PropertyPermission "user.dir", "read";
permission java.io.FilePermission "test/test.txt", "write";
permission com.test.permission.TVPermission "chanel-5", "watch";
};

java -Djava.security.manager -Djava.security.policy=policy/sample.policy -classpath classes/ com.test.security.WatchTV

Now it executes correctly. Now we can understand how java runtime manage permissions under a security manager.
Lets see how actually jdk 1.5 implements the createNewFile method.

public boolean createNewFile() throws IOException {
SecurityManager security = System.getSecurityManager();
if (security != null) security.checkWrite(path);
return fs.createFileExclusively(path);
}

First it gets the Security manager and if it is not null (i.e when running under security manager) check for the write permission. This checkWrite method is like this,
public void checkWrite(String file) {
checkPermission(new FilePermission(file,
SecurityConstants.FILE_WRITE_ACTION));
}
public void checkPermission(Permission perm) {
java.security.AccessController.checkPermission(perm);
}

This finally calls the AccessController as in earlier sample.

3 comments:

kasunbg said...

Nicely explained. Thanks!

Kevin Marshall said...

Great post, thanks for this information....
Web Services

Kevin Marshall said...

Great information thanks for sharing this with us.In fact in all posts of this blog their is something to learn . your work is very good and i appreciate your work and hopping for some more informative posts . Again thanks Web Development Karachi