简体   繁体   中英

Running Javascript in Java: FilePermission denied

Running Javascript in Java, I get FilePermission access denied on both read and write. This happens when the Javascript access a Java method that does some file operations. My Java Swing GUI program itself has no problem reading and writing files on local disk.

Using the following approach to evaluate the script:

URL url = new URL(scriptURL);
InputStream is = url.openStream();
Reader reader = new InputStreamReader(is, Constants.DEFAULT_CHARSET);
engine.eval(reader);

I can get around this by adding the following to Java default java.policy

grant {
    permission java.io.FilePermission "<<ALL FILES>>", "read, write";
};

This is not an equable solution. It would require all users of my program to add it to their own Java policy.

If I supplied my own Java policy file this could be used when running the JAR. However, since the program is executed via Java Web Start, this is not an option. Running Java Web Start on the command line could supply the extra java policy file, but that is not a user friendly option. Adding a JNLP resource property with an extra java policy file doesn't work, since my JNLP isn't signed (my JAR is though, signed).

SEVERE: http://machine/path/to/someJavaScript.js: access denied ("java.io.FilePermission" "/home/username/.program/cache/image8761533877202123654.img" "read")
java.security.AccessControlException: access denied ("java.io.FilePermission" "/home/username/.program/cache/image8761533877202123654.img" "read")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:457)
at java.security.AccessController.checkPermission(AccessController.java:884)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at com.sun.javaws.security.JavaWebStartSecurity.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkRead(SecurityManager.java:888)
at sun.awt.SunToolkit.checkPermissions(SunToolkit.java:912)
at sun.awt.SunToolkit.getImageFromHash(SunToolkit.java:737)
at sun.awt.SunToolkit.getImage(SunToolkit.java:752)
at javax.swing.ImageIcon.<init>(ImageIcon.java:159)
at javax.swing.ImageIcon.<init>(ImageIcon.java:186)
at com.company.gui.ImageHelperStore.get(ImageHelperStore.java:366)
at com.company.gui.BaseComponent.getIcon(BaseComponent.java:1046)
at com.company.gui.GUIScripter$Helper.getIcon(GUIScripter.java:152)
at jdk.nashorn.internal.scripts.Script$\^eval\_.:program(<eval>:32)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:636)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:229)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:387)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:437)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:401)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:397)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:147)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249)
at com.company.gui.GUIScripter.initializeScript(GUIScripter.java:392)
at com.company.gui.GUIScripter.postInitialize(GUIScripter.java:346)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:301)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)e here

If you load script from a String or from an arbitrary java.io.Reader instance, then nashorn script engine treats the script as "untrusted" and so gives only "sandbox" permissions to it (whatever permissions given without "codeBase" in your security policy). But, if you want to have same permissions given to your jar file (ie, inherit permissions of jar file in your scripts), then you have to load script using jdk.nashorn.api.scripting.URLReader ( https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/URLReader.html )

Sample code

You may want to copy the following files under your home directory. To compile and run this, you can use run.sh script below. This sample uses URLReader to load the script. And so the script "inherits" permissions granted to the jar file.

File: Main.java

import javax.script.*;
import java.net.URL;
import jdk.nashorn.api.scripting.URLReader;

public class Main {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager m = new ScriptEngineManager();
        ScriptEngine e = m.getEngineByName("nashorn");
        e.eval(new URLReader(Main.class.getResource("test.js")));
    }
}

File test.js

print("about to exit...");
java.lang.System.exit(0);

File test.policy

grant codeBase "file:${user.dir}/test.jar" {
    permission java.security.AllPermission;
};

File run.sh

javac Main.java
jar cvf test.jar Main.class test.js
java -Djava.security.manager -Djava.security.policy=test.policy -cp test.jar Main

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM