Skip to main content

Firefox Extensions and LiveConnect Security Policy

41 replies [Last post]
franktolstrup
Offline
Joined: 2008-08-22

Hi,

I have a firefox extension using the LiveConnect in firefox and a having a lot of problems with Java exceptions. They cannot be caught in javascript and they seems to make the LiveConnect crash, so if a java exception occurs you need to restart firefox to make LiveConnect work again.

So I have tried testing my firefox extension using u6N, but have some security problems.

To let the java code access the filesystem I use the code adapted from http://simile.mit.edu/wiki/Java_Firefox_Extension

var policyClass = java.lang.Class.forName(
"edu.mit.simile.firefoxClassLoader.URLSetPolicy",
true,
cl
);
var policy = policyClass.newInstance();
policy.setOuterPolicy(java.security.Policy.getPolicy());
java.security.Policy.setPolicy(policy);
policy.addPermission(new java.security.AllPermission());

for (var j=0; j < urls.length; j++) {
policy.addURL(urls[j]);
}

Using 6uN LiveConnect I get a AccessControlException on Policy.getPolicy() and Policy.setPolicy()

How do I set the security of my extension using 6uN LiveConnect?

Frank

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
ndcosta123
Offline
Joined: 2007-10-03

Hi Techxpi, Just checking - if have you filed a report in Sun can you provide the incident ID and we can look into it.

Thanks,
Nelson

techxpi
Offline
Joined: 2009-03-31

Hi ndcosta123 I appreciate your assistance. The email sent after filing the bug mentions a review ID but no incident ID.
"Your report has been assigned an internal review ID of 1490062"

Here is the test case as a Firefox extension:
(see attachment below)
Let me know if you need any more information.

Another issue noticed is that restarting Firefox seems to cause the plugin to crash Firefox. After removing code that invokes the plugin, Firefox stops crashing regardless of being restarted.

kbr
Offline
Joined: 2003-06-16

I wasn't able to download the file (Nelson probably already did), but if the full source code wasn't included in it, we are going to need that, as well as a way to rebuild the test case after making modifications to the source.

techxpi
Offline
Joined: 2009-03-31

The file should still be downloadable, I didn't see a way to add attachments to the bug report. The full source code is included. You can rebuild the test case like any other Firefox extension except for remembering to recompile the .java file. If you need more detailed build instructions let me know.

ndcosta123
Offline
Joined: 2007-10-03

Hi techxpi,

We have opened a bug report 6825869 - it should be visible at http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6825869 in a day or two. You should receive an email with more details soon.

Thanks for putting the testcase together.

Thanks,
Nelson

romano22
Offline
Joined: 2009-04-27

Hello,
I have changed a bit the failcase example. See bellow:
package liveconnect;

import sun.misc.BASE64Encoder;

public class JavaTest {

public static JavaTest build() {
return new JavaTest();
}

public String encode() {
return new BASE64Encoder().encode(new byte[] { 10, 20, 30 } );
}
}

I am trying to use a BASE64Encoder() and I get the following exception:

Error calling method on NPObject! [plugin exception: java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.misc)].

By reading this forum post, I thought the security permission was AllPermission for the code running as a FireFox add-on. Am I mistaken?

BTW, I am using FireFox 3.0.9 and the Java PlugIn version is 1.6.0_13.

Thanks,
Romano

Message was edited by: romano22

kbr
Offline
Joined: 2003-06-16

AllPermission is granted for JavaScript -> Java calls performed within a Firefox extension. You are loading additional Java classes in your example. In order for these loaded classes to have the appropriate (all) permissions you need to use a custom URLClassLoader subclass which grants these permissions. You can not just use a URLClassLoader instance. This is described at http://simile.mit.edu/wiki/Java_Firefox_Extension .

romano22
Offline
Joined: 2009-04-27

Hi kbr,

I was afraid I would have to dig into Java_Firefox_Extension , but I did not want to start without understanding why it wasn't work. Thanks so much for clarifying the problem.

Romano

techxpi
Offline
Joined: 2009-03-31

How do you call back into JavaScript from Java in a Firefox extension?

The JavaJSTest.java example (https://jdk6.dev.java.net/plugin2/liveconnect/examples.zip) uses this

JSObject window = JSObject.getWindow(this);

but it causes the following error when used in a Firefox 3 extension (on the 1.6.0_13 Plugin)
"java.security.PrivilegedActionException: java.lang.reflect.InvocationTargetException"

Passing in a JavaScript object to a Java method works until the JavaScript object is modified. Returning the JSObject after calling .setMember or .setSlot just results in null.

Is this functionality even possible?

Java should be able to return a modified JS Object and properly use .eval given a getWindow context. There is very little documentation available for Java + Firefox.

kbr
Offline
Joined: 2003-06-16

I don't know whether this is possible. One issue is that the netscape.javascript.JSObject API is currently bootstrapped using an Applet instance and you don't have one when you're running as a Firefox extension. I assume that's why you're getting an exception -- what value are you passing into the getWindow() call?

I also don't know what happens at the browser level if a Firefox extension fetches the window object. I'll try to find out from Mozilla.

If you have a small and self-contained test case please file a bug and provide it.

techxpi
Offline
Joined: 2009-03-31

getWindow is being called like this
JSObject window = JSObject.getWindow(this);

The class extends applet. These also generate the same error.

this.getDocumentBase();
this.getAppletContext();

The function below works but when trying to modify the JSObject with setMember or setSlot only nulls are returned.
public JSObject echo(JSObject js) {
return js;
}

I've made a test case. Where do I file the bug?

Given a JavaScript object
var obj = {"msg" : "hello"};
What is the proper way to modify it in Java as a JSObject using setMember/setSlot?

Thank you for your help.

kbr
Offline
Joined: 2003-06-16

File bugs using the instructions here:
http://java.sun.com/javase/6/webnotes/6u10/plugin2/index.html#FEEDBACK

If you don't get a response within a week email me and I'll track down the report.

Given your example you would call for example obj.setMember("msg", "goodbye"). setSlot is for interacting with JavaScript arrays. There are plenty of examples in the new LiveConnect documentation at http://java.sun.com/javase/6/webnotes/6u10/plugin2/liveconnect/index.html .

edwh
Offline
Joined: 2008-09-07

The problems with Java dying after a laptop resume are still happening for me and for other users, including on Update 13. Is someone working on this?

brettz9
Offline
Joined: 2009-01-18

Hello!

This had been so amazingly frustrating--no documentation, changing APIs, and no clear knowledge (at least to Firefox developers getting their info mostly out of its developer site) of whether this very useful LiveConnect would even be fixed in Firefox (most were simply saying it was dead without explanation). So, massive thanks to kbr and edwh for explaining this!

I was wondering when update 12 was scheduled to be pushed out to users? Firefox 3 isn't in beta anymore (already on to 3.1 betas), so this really makes a difference to us and our users, as edwh explained...

Regarding the above issue, if LiveConnect is working now more of how it is supposed to, though, I don't think even this fixed hack should be necessary. It should be possible to just deal with it in JavaScript, no?

bootstrapClassLoader = new java.net.URLClassLoader([new java.net.URL(fileStr)]);

At least it was working this way in earlier versions of Firefox before the more recent decline of (the old) LiveConnect in Mozilla (sometime in FF3.0 beta: https://bugzilla.mozilla.org/show_bug.cgi?id=434658 ).

As a FYI, this page has a recent modification date and has some useful info about future plans: http://www.mozilla.org/js/liveconnect/lc3_proposal.html

(Addition: It'd be really great to know whether LiveConnect can catch Java errors in JS try-catch again, as that would TREMENDOUSLY facilitate incorporate of Java libraries, etc. Thanks...)

Message was edited by: brettz9

brettz9
Offline
Joined: 2009-01-18

And in addition to my try-catch comment just added, I'd also like to know whether "new java.lang.String()" should work in Firefox, as it is not working as of update 11, as it had been working in earlier LiveConnect versions... Thx...

kbr
Offline
Joined: 2003-06-16

Java SE 6 Update 12 is scheduled for release in Q1 '09. See https://jdk6.dev.java.net/ .

It's possible your JavaScript syntax trick for instantiating the URLClassLoader may work; I haven't tried it. The new Java Plug-In should be able to convert the JavaScript array object to a Java array object given that the elements are assignment compatible.

You can definitely catch Java exceptions within JavaScript, portably among browsers, with the new Java Plug-In. The following may be useful:

http://java.sun.com/javase/6/webnotes/6u10/plugin2/liveconnect/

It is safe to say that LiveConnect in its previous incarnation is not being developed actively at Mozilla any more. Instead, the new Java Plug-In assumes responsibility for the implementation of the JavaScript/Java bridge on all web browsers.

kbr
Offline
Joined: 2003-06-16

Also, "new java.lang.String()" works fine for me with the new Java Plug-In.

kimangroo
Offline
Joined: 2009-02-11

Sorry to jump this thread with questions but I'm having trouble finding anyone who can help me with java and Firefox extensions and this thread seemed very relevant.

I'm trying to access a local jar file using javascript code running from an extension chrome dialog window.

So far I've tried:

[code]
var urlClasz = java.lang.Class.forName("java.net.URL");
var urlArray = java.lang.reflect.Array.newInstance(urlClasz,1);
urlArray[0] = new java.net.URL('chrome://test/content/ImageApp.jar');
var cl = new java.net.URLClassLoader(urlArray);
[/code]

&

[code]
var fileStr = 'chrome://test/content/ImageApp.jar';
bootstrapClassLoader = new java.net.URLClassLoader([new java.net.URL(fileStr)]);
[/code]

These both give:

"Error: uncaught exception: Error calling method on NPObject! [plugin exception: java.security.AccessControlException: access denied (java.lang.RuntimePermission createClassLoader)]."

Whereas,

[code]
urlArray = java.lang.reflect.Array.newInstance(java.lang.Class.forName("java.net.URL"), 1);
urlArray[0] = 'chrome://test/content/ImageApp.jar';
bootstrapClassLoader = new java.net.URLClassLoader(urlArray);
[/code]

gives:

"Error: uncaught exception: Error setting property on scriptable plugin object! [plugin exception: java.lang.IllegalArgumentException: Class java.lang.String can not be converted to java.net.URL]."

To be honest I don't really understand what's going on! And can't find much on the net to help. I'd be really, really grateful if someone could show me where the code is going wrong.

Thanks!

tackline
Offline
Joined: 2003-06-19

Untrusted code cannot construct a URLClassLoader directly. However, you can use URLClassLoader.newInstance.

Message was edited by: tackline

kimangroo
Offline
Joined: 2009-02-11

Thanks a lot for replying tackline.

I tried adding newInstance

[code]
var urlClasz = java.lang.Class.forName("java.net.URL");
var urlArray = java.lang.reflect.Array.newInstance(urlClasz,1);
urlArray[0] = new java.net.URL('chrome://test/content/ImageApp.jar');
LINE 39: var cl = new java.net.URLClassLoader.newInstance(urlArray);
[/code]

Unfortunately now I get this error:

"Error: NPMethod called on non-NPObject wrapped JSObject!
Source File: chrome://test/content/overlay.js
Line: 39"

Hey, it's a new error message so that must mean progress! I wondered if you knew what might be going wrong?

kbr
Offline
Joined: 2003-06-16

Remove the "new" from "new java.net.URLClassLoader.newInstance" and it should work.

kimangroo
Offline
Joined: 2009-02-11

Thanks so much guys that part of the code seems to be working now!

but....

the bit where I actually call my class isn't!

[code]
var aClass = java.lang.Class.forName("ImageApp", true, cl);
var aStaticMethod = aClass.getMethod("ImageApp", []);
var greeting = aStaticMethod.invoke(null, []);
[/code]

I get an error for the first line:
"Error: uncaught exception: Error calling method on NPObject! [plugin exception: java.lang.ClassNotFoundException: ImageApp]."
I get a similar error if I replace ImageApp with ImageApp.class.

My jar is very simple and consists of the entry point class ImageApp.class and a JImagePanel.class. I got the code from http://www.javalobby.org/articles/ultimate-image/.

Is there some special naming convention I should obey?

Sorry for the very basic and probly very stupid questions! I'd just love to get one working example my end and then I can tweak it from there on.

EDIT**********************

Ok say I had a HelloWorldApp.jar which contained HelloWorldApp.class with:
[code]
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); // Display the string.
}
}
[/code]

And the jar was located on my C: drive.

Could someone show me the code I would use to call the app?

Thx again!

Message was edited by: kimangroo

tackline
Offline
Joined: 2003-06-19

You don't need the .class - that's just a very strange thing the code attribute of the applet tag does.

I guess the obvious thing to check is that you can open the java.net.URL object and read from it normally ignoring the class loader stuff.

In the reflection code you appear to be attempting to call the constructor. In the class file constructors actually have the name "" and you can't call them as methods. You should use Constructor to call it.

kimangroo
Offline
Joined: 2009-02-11

Hi tackline, sorry about the edit I didn't refresh my browser so I missed your post.

The code I'm using is just something I copied and pasted from here:
https://developer.mozilla.org/en/Java_in_Firefox_Extensions

I didn't mean to call the constructor, all I'd like to do is "start" my java .class file with some parameters just like I would if I ran it from the command line. So I guess the main method is what I want to run, like the helloworld app above.

Do you think you could tell me the code you would use to run that helloworld app in the example above? If I could get that to work, hopefully I'd be able to work my way through after that...

I'd gladly check that I could open the java.net.URL etc except that I don't know how!

kbr
Offline
Joined: 2003-06-16

You can't use a chrome URL in a URLClassLoader. You need to convert it to an http protocol URL. There is code in the Firegoose extension at http://gaggle.systemsbiology.net/docs/geese/firegoose/ which shows how to do this. Look in firefox/components/JavaObjectFactory.js, specifically the function assigned to "JavaObjectFactory.prototype._getExtensionPath".

kimangroo
Offline
Joined: 2009-02-11

Hi kbr thanks for the reply!

I checked out the function you linked, but it doesn't seem to work with extensions you are developing dynamically ie not installed yet. Checking it out with other addons though it seems to return a file path of the type:
file:///H:/Java/etc..

Unfortunately I've tried using file:, file:/, file:// etc but with no luck.

It would be great if you could show me the code you would use to get that helloworldapp above working and then maybe i could work out exactly what I'm doing wrong. I'm sure it's something very stupid.

Thx again for your time.

Edit**********************
Ok turns out I was doing a couple of things wrong.
1) With that javascript you need to stop the class being main and give it a name that you reference with getMethod instead.
2) I have trouble accessing files that are not on my C: drive for security reasons. When the jar is on C: there isn't a problem.

Message was edited by: kimangroo

edwh
Offline
Joined: 2008-09-07

Is this supposed to work with Update 12 from http://download.java.net/jdk6/ ? I'm getting reports that it doesn't.

kbr
Offline
Joined: 2003-06-16

Yes, the permissions problem should be solved in 6u12.

Note that the new plug-in does not support all of the LiveConnect syntax that was supported with the old plug-in. It might be that the Firefox extension requires some tweaks to work with the new plug-in. The bug fix I filed above against Firegoose shows how I modified that extension to work with the new plug-in.

edwh
Offline
Joined: 2008-09-07

Thanks for your reply. I'm still struggling a little with this, though. My original code was:

urlArray = java.lang.reflect.Array.newInstance(java.net.URL, 1);
java.lang.reflect.Array.set(urlArray, 0, firefoxClassLoaderURL);
bootstrapClassLoader = java.net.URLClassLoader.newInstance(urlArray);

I see from your diff that you've replaced the newInstance call in the last line with a new, but what should I do with the first line?

I've experimented slightly at random, but not hit on the right thing, and I can't seem to find the FireGoose source to check what they did.

kbr
Offline
Joined: 2003-06-16

This should be (approximately)

urlArray = java.lang.reflect.Array.newInstance(java.lang.Class.forName("java.net.URL", 1));
urlArray[0] = firefoxClassLoaderURL;
bootstrapClassLoader = new java.net.URLClassLoader(urlArray);

edwh
Offline
Joined: 2008-09-07

And we're there.

Minor bracket typo; should be:

urlArray = java.lang.reflect.Array.newInstance(java.lang.Class.forName("java.net.URL"), 1);

Thanks very much, this will make my life much easier, and that of my extension's users.

edwh
Offline
Joined: 2008-09-07

I've seen some problems with Update 12 and Firefox, though.
* I can't get the Java Console to come up - after trying once, it greys out and never opens.
* If I suspend a laptop and resume it, Java stops working - I'm not sure why because I can't open the Java Console to check.

kbr
Offline
Joined: 2003-06-16

The "Java Console" menu option isn't working yet with the new Java Plug-In, though we aim to make it work again in a future update release. For the time being, if you're on Windows, you can use the Java system tray icon to open the console. On other platforms (or on Windows as well), use the Java Control Panel, Advanced tab to select "Show Java console".

brettz9
Offline
Joined: 2009-01-18

Besides my additional question just added now about try-catch, I was wondering...

Since the new spec deprecates the java/netscape/Packages globals in favor of the new per-applet Packages, it is unclear to me whether Firefox extensions are supposed to include code like and document.getElementById('app') or whether they are to continue into the future to have access to the globals. The applet usage would really be cumbersome and probably usually unnecessary in extension code... Some expansion of the Sun documentation would be great, since there's not much there for extension developers... Thanks...

kbr
Offline
Joined: 2003-06-16

Firefox and the Java Plug-In will continue to support the global java/Packages keywords, in particular in the context of Firefox extensions.

In the context of normal web pages embedding applets, it is strongly recommended to move to the portable per-applet Packages keyword.

cbare
Offline
Joined: 2004-02-02

I wrote an extension called Firegoose that uses the same technique from Simile to access Java code in jars in a Firefox extension. I'm getting a security exception saying "access denied (java.lang.RuntimePermission getClassLoader)" on the following line of javascript:

var bootstrapClassLoader = new java.lang.URLClassLoader(javaUrls);

Please add another vote for this to be fixed.

Thanks,

-chris

kbr
Offline
Joined: 2003-06-16

Thanks for the pointer to FireGoose. With a small modification (http://gaggle.systemsbiology.net/mantis/view.php?id=98) I was able to get it to run and reproduce the underlying problem where Firefox extensions using Java weren't being granted enough permissions. This bug in the Java Plug-In, 6745455, has now been fixed, so if the slight syntactic change is made in the FireGoose source code then it will work in Firefox 3 with the new Java Plug-In in the forthcoming Java SE 6 Update 12.

cbare
Offline
Joined: 2004-02-02

Thanks a lot kbr! I'm stoked that using Java in a Firefox extension is getting some respect.

-chris

kbr
Offline
Joined: 2003-06-16

Sorry for the delay in replying. We've recently received a couple of reports about Firefox extensions failing to work with the new Java Plug-In, yours included. 6745455 has been filed to track the issue and we think we know what needs to be changed to make this work. However, part of the fix is risky, involving elevating privileges for JavaScript-to-Java calls, so I do not think we can fix this in 6u10. We may be able to fix the LiveConnect breakage when the failure occurs. As a workaround you can use the classic Java Plug-In. Sorry about the breakage.

edwh
Offline
Joined: 2008-09-07

My extension is also broken by this.

What do you mean by using the Classic Java Plugin - the Update 7 version? Is it possible to install this separately, on top of Update 10?

mbien
Offline
Joined: 2007-04-29

@edwh
on windows you can just disable it in the Java Control Panel.