Closed Bug 109067 Opened 23 years ago Closed 23 years ago

JavaScript to signed Java applet security problems

Categories

(Core Graveyard :: Java: OJI, defect)

x86
Windows 2000
defect
Not set
major

Tracking

(Not tracked)

RESOLVED INVALID

People

(Reporter: robert.landon, Assigned: joe.chou)

References

()

Details

From Bugzilla Helper:
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:0.9.5+)
Gecko/20011108
BuildID:    2001110803

The applet I've developed uses sockets to connect to multiple machines as part
of its operations.  It was initially done with IE using a signed cab file.  This
works fine and I am now migrating to Netscape 6.x.  I created a self-signed jar
for testing and could not get the proper socket permissions.  I've simplified
the test to simply attempt to delete a file from the local file system and
noticed that if the call is made in the init() or start() methods of the applet,
it succeeds.  If it is called from JavaScript, it does not.  I installed the
Java plugin 1.3.1 and 1.4 beta 3.  The same test succeeds in IE 6.0 with the
plugin, but still fails with Netscape 6.2 and Mozilla 0.9.5+.  I've noticed
other bugs reporting similar issues (URLConnection) and they've been marked
resolved with plugin 1.4 beta.

Reproducible: Always
Steps to Reproduce:
1. Create signed jar file that has an applet with a start() and a test() method.
 Attempt to delete a file in the start() method.  Call start() from test() also.
 Make sure to put System.out.println() calls to monitor the calls.
2. Create HTML that loads said jar file as an applet.
3. Create a button on the HTML that calls test() via JavaScript.

Actual Results:  When the HTML is loaded, the user is prompted to allow
permissions to the applet.  After granting permissions, the start() call
succeeds, but the test() call fails.

Expected Results:  A signed applet with AllPermissions should allow this
operation in both cases.

See http://landons.freeservers.com/mozilla.
I've come up with a work-around that is probably too complicated for most 
cases, but works fine for what I'm doing.

1) Create a thread in the start() method of the applet.
2) When a JavaScript to Java call is being made, proxy any privileged calls 
into that thread.
3) Tear down the thread in the stop() method of the applet.
Actually, this is (imo) no bug. This is how the Java Security Architecture works.  

Please refer to
http://java.sun.com/j2se/1.3/docs/guide/security/doprivileged.html for further
information.

If you wrapp your code in
  AccessController.doPrivileged(new PrivilegedAction() {
    public Object run() {
      // privileged code goes here
    }
  });

it will work.

Actually I do not know, if the JavaScript code SHOULD be included, when
determining the code permissions, so leaving UNCONFIRMED for now.
I've done some more investigation based on Niklas' comments.  I'm somewhat of a 
newbie to the Java world (and definitely to the Java 1.2 security world), so 
bear with me.

The doPrivileged code did work.  My understanding is that this is because it 
stops checking security at that point and is still within my signed applet, so 
it has the appropriate permissions.  Prior to using this call, the checks would 
continue into the LiveConnect/JavaScript side, which was unsigned and did not 
have the appropriate permissions.

In my original test case, it only worked using a method called by the JVM 
(init, start, etc.) and did so because system code has all permissions.  
Therefore, all parties were trusted and the operation was allowed.

If the above is true, I understand the logic and agree with Niklas.  The 
question for me then moves to JavaScript.

Without using the doPrivileged, this works fine using Internet Explorer with 
the same, latest Sun JVM that replaces the MS JVM.  Would the argument be that 
this is actually an IE security hole or is Mozilla/Netscape being too 
restrictive with JavaScript code?
I have a similar problem.

I have a signed applet that does trusted operations. Everything works fine in 
IE, and in Netscape if I don't call the java method from Javascript, but I 
have an AccessControlException whenever I try to call my method in Netscape 
6.2.

Please note that there used to be a workarounf in Netscape 4.x. Just running a 
trusted applet from the same jar file once without calls from Javascript, 
allowed future calls to applets from Javascript to work.

But this workaround does not work in Netscape 6.2.

I believe this should be logged as a bug since the applet and the Javascript 
are from the same origin, which satisfies Netscape's same origin policy.

Thanks.

- Dan Serfaty (dserfaty@documentum.com)
This is not a bug in Mozilla.  This security exception is raised by design 
under the new Java plugin from Sun.

See http://java.sun.com/products/plugin/1.3/enhancements/security.html
Specifically javascript-to-java communication.

In order to call a priviledged method from javascript you will need to sign 
your script and have UniversalJavaPermissions set for javascript.
There is still a hole somewhere here.  If you look at my Additional Comment #1, 
by starting a thread (VM context), you can proxy privileged calls from unsigned 
JavaScript.  My applet is signed.  This works.  I'm doing it.

In addition, IE5+ using the JVM plugin works fine with same unsigned JScript to 
same signed Java applet WITHOUT proxy.

I'm using the same code for both now (proxied) because I was using a thread to 
keep sockets from blocking my main thread anyway, so it didn't hurt anything.
Also, as in comment #4, my JavaScript and applet are coming from the same 
source.

Using code from comment #2 worked also, but meant I had to have different code 
for every privileged call.  If that's the way it ends up having to be, so be it.
From the link in comment #5

In JavaScript-to-Java communication, a call from JavaScript to an applet is 
allowed only if one or both of the following is true:

1. The origin (URL) of the page is the same as the origin of the applet; 
2. JavaScript is signed and UniversalBrowserRead permission is enabled for 
JavaScript.

My case is satisfied by 1.

So, does that means that you need:
  AccessController.doPrivileged(new PrivilegedAction() {
    public Object run() {
      // privileged code goes here
    }
  });

If so, that is not required of the Java plugin under IE, using the same JAR and 
script code.
Hi,
I attempted the suggested solution using the approach in #2.
i.e.
...
import java.security.AccessController;
import java.security.PrivilegedAction;
...
...
 AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        // privileged code goes here, for example:
                         _enum = CommPortIdentifier.getPortIdentifiers();
                         System.out.println("Port identifier enumeration set.");
                        return null; // nothing to return
                    }
                }); 

However, this results in a 
ClassNotFoundException:java.security.PrivilegedAction  being thrown at runtime
I am running IE5 with the latest Microsoft VM on WINNT .
That is a Sun VM way of doing things.  I write code that works in IE w/MS VM, 
IE w/Sun VM and Netscape 6 w/Sun VM.  I want to be able to easily write re-
usable and portable Java AND JavaScript code.  It's not impossible to do it 
this way, it's just inconvenient.  It appears as though it may be necessary, 
however.

I have not yet tried writing this with the same Java code to run under the 
Microsoft VM on IE and the Sun VM on both using 
the 'AccessController.doPrivileged' and 'PolicyEngine.assertPermission'.  What 
if you also need to run using the Netscape Object Signing for 4.x (luckily I 
don't)?  What a mess!

As a Mozilla newbie, this is how the security in this situation seems to break 
down:

1) To perform a privileged operation (file access, etc.), you must either be 
signed (normal) or your security policy must be wide open in some fashion to 
allow unsigned code (inadvisable).
2) Assuming the signed route, if your JavaScript is signed, then trusted 
operations should work (haven't tested, but assume this works based on other 
comments here).
3) If your JavaScript is unsigned, you must ask the AccessController if you 
have permission to perform an operation BEFORE it checks backwards into the 
unsigned JavaScript portion of the stack.  This keeps the security manager from 
continuing its check and finding unsigned code calling it.  If you call 
privileged code from a thread created during startup of the applet, you don't 
have to check permissions because all of the code is your Java applet and the 
entire call stack is signed and privileged.

The security problem that Mozilla seems to be trying to cover is rogue 
JavaScript calling a signed applet to do destructive things that the applet may 
allow you to do.  So... the only way to prevent this situation is via signed 
JavaScript calling your signed applet.

I guess I'm breaking this rule for my own ease of use, but potentially leaving 
a security hole, depending on what I'm exposing to JavaScript via my applet.

Ok ... I guess there isn't a bug here after all.  It's just divergent from IE 
and took a while to sink in.  Obviously IE opens the world to ActiveX controls 
and Java applets via JScript since you can't sign the JScript.  That's the 
security problem and that's what Mozilla is trying to allow us to handle.  If 
we ask the AccessController for permission, we will be allowed to do privilege 
code from unsigned JavaScript.

I move to strike this bug from the record.
Status: UNCONFIRMED → RESOLVED
Closed: 23 years ago
Resolution: --- → INVALID
Hmm. It still seems like there is some inconsistent behavior here. Out test 
setup is an HTML page containing a Netscape signed applet, javascript that 
calls the applet, and a button to trigger the javascript.

We ran the test using NS 6.2 and several version of the 1.3 plug-in.

Here�fs the results:

Test 1: Signed applet, default policy

If the page is loaded with the default policy file(s), a security dialog is 
presented to the user during applet startup. Provided the �egrant�f is pressed, 
the applet starts up just fine. Pressing the button, which exercises the 
javascript, results in a securityexception being thrown by the applet.

Test 2: Signed applet, grant AllPermissions to all domains

If the page is loaded with a .java.policy file that grants AllPermissions to 
all domains, the applet starts without asking the user to grant permission, and 
the button-activated javascript executes without an exception.

Test 3: Signed applet, grant AllPermissions to test page�fs domain.

The .java.policy file was modified to grant AllPermissions to anything coming 
from the base domain which served the page. The applet starts without asking 
the user to grant permission. However, the button-activated javascript throws a 
security exception.

So, it appears that the Javascript does not have the same codebase as the 
applet. If it did, Test 3 should have behaved the same as Test 2. The grant for 
Test 3 appears to be correct, because the applet is trusted and does not 
require the user to grant privileges.

It seems the security policies for javascript  to java communications should be 
controlled by the java policy manager. I should be able to grant fine grained 
permissions based on codebase or signer or both.
Chris Petersen is a new QA contact for oji component. His email is:
petersen@netscape.com
Assignee: joe.chou → petersen
fixing small error for pmac@netscape.com (filter with : SPAMMAILSUCKS)
Assignee: petersen → joe.chou
QA Contact: pmac → petersen
Product: Core → Core Graveyard
You need to log in before you can comment on or make changes to this bug.