Restricting Signed Java Applets

Posted by Arvind Doraiswamy on March 19, 2013 at 3:39 PM
I was recently on a project where I was looking at Java applets. While looking at them, I found that the moment you sign an applet, you give it carte-blanche. It downloads to your hard drive and if it is malicious, for whatever reason, it could do a lot of bad things like deleting files from your disk or connecting to sites you didn't even know existed.

Our client wanted us to look at the overall risks of using signed applets at all. After a little bit of research I wrote up a brief report for them which I certainly will not share :) ... but also this little blog post which summed up on how it's possible to limit the power that signed applets have, which I'm happy to share.

There's a ton of information on the Internet on how to sign Java applets and restrict unsigned Java applets as well. Very strangely there is very little information on doing the same for signed applets.

I did manage to find information which eventually helped me out; just that it took an insane amount of searching. Hence this little blog..which just collects all the information I found and puts it in 1 place.

First of all, the reason (as you already most probably know) to restrict signed applets, is that they're all powerful and can perform dangerous file I/O and network operations. So it's a nice thing to be able to restrict them from doing so, if needed. So here are the steps to do so, in a nutshell:

a) Sign your Java applet using keytool and jarsigner. A self signed applet is sufficient for demo purposes. The same logic can be used in case a trusted CA signs the certificate.

b) Once the applet is signed it's usually packaged into a JAR file prior to deploying it.

c) It's then deployed by embedding it into the HTML of a web page.

d) When the user visits the page, there's a pop-up which will now appear, asking the user to grant the applet additional permissions. Note here that if you click Run, the signed applet has complete control and can make numerous file and network I/O calls. If however, you click Cancel, you're not granting it permissions. The applet still runs (contrary to what one might intuitively think) but behaves like an unsigned applet.

e) What we now want to do though, is to limit what the applet can do, when the user clicks Run. For example: If all the user wants to do, is write to /tmp and nothing else, why should it have a million other privileges?

f) There's 2 ways to do it. One is to call every single relevant method in the applet from JavaScript. The second way is to write a policy in java.policy. Without frustrating you further, I'm going to show you, with a little sample code on how to do both.

g) First of all here is the Java code that I used as a POC. It's grabbed and tweaked from some tutorial online and not my own.

import java.applet.*;
import java.awt.*;
import java.io.* ;
import java.util.*;

public class FirstApplet extends Applet{
public void init() {
createFile("/abc/testsignapplet.txt");
}

public void test_HTMLbutton_method_invoke() {
createFile("/abc/booboo.txt");
}

public void test_js_onload() {
createFile("/abc/doodoo.txt");
}

private void createFile(String filename) {
FileOutputStream out = null;
try {
out = new FileOutputStream(filename);
out.write(("Testing jar signing process...:" + new Date()).getBytes());
} catch(Exception ex) {
ex.printStackTrace();
} finally {
try {
if(out != null) {
out.close();
}
} catch(IOException e) {}
}
}
}

h) Here is how you must call the public methods of the applet from either an HTML element or from JavaScript. The line in the last < script > block which embeds the applet is possibly not the best way to do things; it's just there to show you guys how to call a method via HTML and JS, which is the point of the post.

i) Doing so, will cause the applet to still behave as an unsigned applet. If there's any malicious code in any of those functions, it's not going to be able to break out and cause havoc.

j) The other way of limiting the operations an applet can perform is by editing the file called java.policy. On a Ubuntu system, by default this file is inside your home directory. It is named .java.policy.

k) Back the file up and then delete all the lines in that file. Now add these lines to the file. This limits the applet loaded from http://localhost/applets/ from writing to any other directory except /abc.

grant codeBase "http://localhost/applets/*" {
permission java.io.FilePermission "/abc/*", "write";
};

l) Note that a cool GUI tool called policytool can also be used for this purpose. If you have JRE or/and JDK on your machine, you should have policytool as well. You can add/edit/remove policies using it as well.

m) Test your applet using appletviewer first. It's a tool which you can use to check if your policies are working properly, before deploying the applets everywhere.

appletviewer -J-Djava.security.policy=/home/arvind/.java.policy sample.html

n) If the results are as expected, launch the applet in the browser. All the HTML and JS calls to methods should be blocked :)

----------

p.s - It's a good idea to have the Java Console launched while you're doing this stuff. It throws exceptions that you can then see and modify your approach accordingly. The Java Console can be launched using javaws -viewer and ticking 'Show Console' in the Advanced Tab.

Other Java related settings can be tweaked too in here. A good guide to follow can be found here.

 

 

Topics: developer guidance, application security

Arvind Doraiswamy

Written by Arvind Doraiswamy

Arvind is a Senior Security Engineer who focuses on conducting security assessments for clients, contributing articles to our secure coding knowledgebase, and writing tools to improve our company's security testing efficiency for clients.