Signed applets called from javascript - how/where to load policy file?

I'm running into some apparently well-known problems with signed applets accessing a client machine's hard drive.

So, I can get things to work if I place the following two lines in my 'local' JDK installation:

permission java.io.FilePermission"${user.home}/x.properties","read,write";

permission java.util.PropertyPermission"user.home","read";

These let me a) read the user's home directory and b) read/write a file that's located there.

What I don't want to do is edit the java.policy file, but I'm having problems loading a separate policy file. The app server we run with our product is jetty, and I'm assuming I would be passing in the '-Djava.security.policy=='filename' with the other jetty start-up parameters- is this a correct assumption? And, what path do I give for the file, will I need to put it somewhere in the .war file we distribute, or in the JDK installation on the server? If it's on the server, will client machine's know about these extra rights?

I'd *REALLY* appreciate any help I could get on this...

thanks in advance,

+0^^

[1223 byte] By [Tom_Catesa] at [2007-10-1 6:58:17]
# 1

> The app server we run with our product is jetty, and I'm assuming I would be passing in

> the '-Djava.security.policy=='filename' with the other jetty start-up parameters- is this a

> correct assumption

the host settings have nothing to do with the client settings. If I were to open a url like:

http://myServer/somePageWithAnApplet

the applet will run on My computer with MY jre settings not on myServer.

If 100 clients on 100 different computers will open that page thei all need to adjust their

policy settings.

Or you can sign the applet and all 100 users will need to click yes when

asked if they trust your applet.

http://forum.java.sun.com/thread.jsp?forum=63&thread=524815

second post

If the method in your signed or "trusted" applet wants to access local file system but

that method came from javascript (which should be untrusted) it would not work from

jre 1.4.2 and up since they fixed the but that trusts javascript.

To add a policy you can add a .policy in the home directory of the user check out the

java.security

policy.url.1=file:${java.home}/lib/security/java.policy

policy.url.2=file:${user.home}/.java.policy

Or add your own:

policy.url.3=file:${user.home}/ourCompany.policy

harmmeijera at 2007-7-9 17:29:55 > top of Java-index,Security,Signed Applets...
# 2

Sorry for typing rubbish again:

... s to access local file system but that method came from javascript ...

should be

... s to access local file system but that method was called from javascript ...

policy.url.3=file:${user.home}/ourCompany.policy

should be

policy.url.3=http://ourCompanyIntranet/java/ourCompanyPolicy.policy

Since this is the easyest way to update everyones policy in one go.

harmmeijera at 2007-7-9 17:29:55 > top of Java-index,Security,Signed Applets...
# 3

THanks for info! I'd gotten around to adding my policy info to a file named .java.policy in the users home directory, which worked. RE: the solution to add my own policy file to the java.security file - this still needs to take place on each client machine's java.security file, correct? I guess there's really no way to do all this from the server if that's the case.

thanks again

tcatesa at 2007-7-9 17:29:55 > top of Java-index,Security,Signed Applets...
# 4

> he solution to add my own policy file to the java.security file - this still needs to take

> place on each client machine's java.security file, correct?

Yes

> I guess there's really no way to do all this from the server if that's the case.

I think if its a company's intranet you can do so through log in scripts or something.

harmmeijera at 2007-7-9 17:29:55 > top of Java-index,Security,Signed Applets...
# 5

The right way to do it "from the server" is to sign your applet, as someone already suggested. You should not discard this advice, as this is the normal way to obtain privileges for your applet. Playing with the policy file is a "development time trick" that allows you to concentrate on your code, rather than on applet signing.

Now, if you make calls from JavaScript, there is a way to overcome this, by explicitly asking the AccessController class (see API) to gran the privilege.

baftosa at 2007-7-9 17:29:55 > top of Java-index,Security,Signed Applets...
# 6

> Playing with the policy file is a "development time trick"

In our company we explicitly disabled the signature rubbish. With all the effort that sys

admins put into securing the desktops SUN just asks the (ignorant) user if he she

trust any signed applet. If any 3rd party service provider needs to do privileged stuff with applets they should tell us what to put in the policy.

Signing doesn't do anything in our company.

Our company is not an exception in this so I view signing the applet as a "development time trick" and policy as a maintainable way of dishing out privileges

where needed.

> by explicitly asking the AccessController class

Asking for more access should only be possible when current code and the call stack

has this privelege (or so I thought).

SUN has provided us with the AccessController.doPrivileged() to ignore the call stack

completely and only check the method calling the doPrivileged method.

Thereby cercomventing their own security:

"Permission checks work by checking the entire call stack. Every class on the call stack must have the requisite permission, or the security check fails. "

....

What this situation calls for is some way for LoggingSM to insist "I know what I am doing when I open the log file, so there is no need to check the call stack any further."

The AccessController.doPrivileged() method neatly solves the problem.

http://java.sun.com/developer/TechTips/2000/tt1128.html

Credit goes to baftos because I thought the doPrivileged was just a bug. I thought it

was like saying "hello SUN security stop bugging me in writhing this malicious program"

Apperantly it's more like "hello SUN security, I'm a good boy now trust what I'm doing"

harmmeijera at 2007-7-9 17:29:55 > top of Java-index,Security,Signed Applets...
# 7

Thanks for pointing to me the usefulness of playing with policy files in the real world. I must admit that I never thought about it this way. This is because I was always involved with applets for very general consumption (anyone on the Internet). In such a situation, do you know any solution except the "certificate ****"?

Now a bit more about doPrivileged(). Suppose you write a method

doSomethingDangereous(). Your applet is well behaved and will not call this without user permission. The method is public for good reasons, you want to call it from a GUI handling package and we must separate business logic from presentation, don't we? Now the hacker gets your applet somehow (perhaps by honestly buying it). He decompiles your code (piece of cake) and finds this method. He puts the applet on his own page with his own JavaScript calling doSomethingDangereous(). Note that if the applet was signed, YOU seem to be the one to blame, not the hacker! (The user accepted YOUR certificate!).

Do you know of any solution to this dilema? This is not a puzzle, it just bugs me and I don't know the solution.

Thanks!

baftosa at 2007-7-9 17:29:55 > top of Java-index,Security,Signed Applets...
# 8

I read my own previous post and I relize I did not explain well the doPriviledged() part. Here is the code:

package mygui;

import mybussinesslogic.*;

public class IntentionallyExposedToJavaScript

{

public void doSomethingDangereousAfterAskingTheUser() {

...

if ( userOK )

{

NotToBeCalledFromJavaScript n = new NotToBeCalledFromJavaScript();

n.doSomethingDangereous();

}

}

package mybussinesslogic.*;

public class NotToBeCalledFromJavaScript

{

public void doSomethingDangereous() {

AccessController.doPriviledged( ... );

}

My problem is that the hacker can call doSomethingDangereous(), although I wanted to expose only doSomethingDangereousAfterAskingTheUser().

baftosa at 2007-7-9 17:29:55 > top of Java-index,Security,Signed Applets...
# 9

Maybe you didn't realize but my previous post was sarcastically ment:

"hello SUN security stop bugging me in writhing this malicious program"

and

"hello SUN security, I'm a good boy now trust what I'm doing"

Are in a practical sense exactly the same.

SUN should either remove the stack check or the doprivileged. The stack check takes up

valuable resources for nothing since a malicious program can easily circumvent that.

Your post about a malicious user abusing your (CA) signed applet to ruine someone's

system is correct, it would not be difficult. A CA signed applet will not even ask a user to

trust or not. This is one of the reasons we have the usepolicy in affect, but this cannot be

used on "grandma's old PC" since it's too complicated for users to do such things.

> YOU seem to be the one to blame, not the hacker! (The user accepted YOUR

> certificate!).

Actually you are to blame, because you made software that exposes a vonurability

other people can take advantage of.

what you can do before calling the doprivileged private method is check the call stack.

So your signed applet has a public method checking the callstack, if this lookes OK

that method will call the private doprivileged method.

Here is the example

package t;

import java.util.Properties;

import java.applet.Applet;

public class test extends Applet {

public test(){

startingPrivileged();

}

public void startingPrivileged(){

System.out.println("this is the stack");

try{

throw new Exception("get the call stack");

}catch(Exception e){

StackTraceElement stack[] = e.getStackTrace();

for (int i=0; i<stack.length; i++) {

System.out.println("file: " + stack[i].getFileName() + " method: " + stack[i].getMethodName() + " class: " + stack[i].getClassName() + " at " + new Integer(i).toString());

}

// this is a really simple check to see if this method was started from the t. package

// a good hacker can just create it's own package named t and take advantage of this method

// if this method was started from the same package there is no reason to make this method

// public, protected would work.

// there must be a better way to check if this method was called by "your" or "trusted" code

if(stack[1].getClassName().startsWith("t.")){

dosomePrivileged();

}

}

}

private void dosomePrivileged(){

System.out.println("this is the method that does privileged stuff");

}

public static void main(String args[]) {

new test();

}

}

>

harmmeijera at 2007-7-9 17:29:55 > top of Java-index,Security,Signed Applets...
# 10

The better solluting is rather obvious. Reducing the scope of your privileged method to

package.

Make sure your packages are in

mycompany.myapplication.events

and

mycompany.myapplication.gui

This site got some thips:

http://java.sun.com/security/seccodeguide.html#gcg3

* Static fields

* Reducing scope

* Public methods and fields

* Protecting packages

* Make objects immutable if possible

* Never return a reference to an internal array that contains sensitive data

* Never store user-supplied arrays directly

* Serialization

* Native methods

* Clear sensitive information

harmmeijera at 2007-7-9 17:29:55 > top of Java-index,Security,Signed Applets...
# 11

The hacker can be prevented from creating his own classes with my package name by using sealed packages (never did, but this is what I understand).

Therefore, using sealed+getStackTrace whould do the trick. Do I miss something? Oh yes, of course: getStackTrace() is since 1.4 only and as a "generic" applet developer, I still struggle with older versions and even with Microsoft VM.

baftosa at 2007-7-9 17:29:55 > top of Java-index,Security,Signed Applets...