签名的applet在从javascript调用时给出AccessControlException:访问被拒绝

时间:2020-12-04 20:30:55

I have an easy self-signed an applet (done with keytool and the jarsigner):

我有一个简单的自签名小程序(用keytool和jarsigner完成):

public class NetAppletLauncher extends JApplet {

    private static final long serialVersionUID = 1L;

    public void init() {
        exec("notepad c:/hello.txt");
    }

    public void exec(String command) {

        try {

            // launch EXE and grab stdin/stdout and stderr
            Process process = Runtime.getRuntime().exec(command);
            //      OutputStream stdin = process.getOutputStream();
            InputStream stderr = process.getErrorStream();
            InputStream stdout = process.getInputStream();

            // "write" the parms into stdin
//          stdin.write(arguments.getBytes());
//          stdin.flush();
//          stdin.close();

            // clean up if any output in stdout
            String line = "";
            BufferedReader brCleanUp = new BufferedReader(new InputStreamReader(stdout));
            while ((line = brCleanUp.readLine()) != null) {
                //System.out.println ("[Stdout] " + line);
            }
            brCleanUp.close();

            // clean up if any output in stderr
            brCleanUp = new BufferedReader(new InputStreamReader(stderr));
            while ((line = brCleanUp.readLine()) != null) {
                //System.out.println ("[Stderr] " + line);
            }
            brCleanUp.close();

        } catch (Exception exception) {
            exception.printStackTrace();
        }

    }

}

Basically, what it does, is that it executes 'notepad c:/hello.txt'.

基本上,它的作用是执行'notepad c:/hello.txt'。

Then i embed the applet in html:

然后我将applet嵌入html中:

<applet id='applet' name='applet' archive='NetAppletLauncher1.jar' code='src.NetAppletLauncher' width='100' height='100' MAYSCRIPT ></applet>

When i visit the page, JRE starts and asks me if i want to start this applet and if i trust it. I press ok. Then notepad starts - as it should. No problem here.

当我访问该页面时,JRE启动并询问我是否要启动此applet并且如果我信任它。我按好了。然后记事本开始 - 应该如此。这里没问题。

But then i add this into the HTML-page:

但后来我将其添加到HTML页面中:

<p class="link" onclick="document.applet.exec('calc');">remote desktop2</p>

Now when i press on this text, calc should start - right? But this gives me:

现在,当我按下这个文本时,计算应该开始 - 对吧?但这给了我:

java.security.AccessControlException: access denied (java.io.FilePermission <<ALL FILES>> execute)
    at java.security.AccessControlContext.checkPermission(Unknown Source)
  • whats up with this? Why does it give me a security exception now, but it could start notepad before?
  • 怎么了?为什么它现在给我一个安全例外,但它可以在之前启动记事本?

4 个解决方案

#1


The Java 2 security model requires (roughly) that every frame on the stack must be granted a permission for the access control context (acc) to have that permission. JavaScript is on the stack and does not have file access permissions.

Java 2安全模型(大致)要求必须为访问控制上下文(acc)授予堆栈中的每个帧以获得该权限。 JavaScript位于堆栈中,没有文件访问权限。

#2


Solved the problem with, in Java:

用Java解决了这个问题:

exec(getParameter("command"));

and then in JavaScript:

然后在JavaScript中:

<script type="text/javascript">

function exec( command ) {

    var applet = "<applet id='applet' style='visibility: hidden' name='applet' archive='NetAppletLauncher4.jar' code='src.NetsetAppletLauncher' width='20' height='20' MAYSCRIPT ><param name='command' value='" + command + "' />Sorry, you need a Java-enabled browser.</applet>";

    var body = document.getElementsByTagName("body")[0];
    var div = document.createElement("div");
    div.innerHTML = applet;
    body.appendChild(div);

}

</script>

#3


I agree : it is prohibited to manipulate a signed applet from javascript, and the workaround is to rewrite the applet tag in javascript in the page document.

我同意:禁止从javascript操作已签名的applet,解决方法是在页面文档中的javascript中重写applet标记。

I found this source with a bit of theory proving we are right http://docs.oracle.com/javase/tutorial/deployment/applet/security.html#jsNote

我发现这个来源有一些理论证明我们是对的http://docs.oracle.com/javase/tutorial/deployment/applet/security.html#jsNote

#4


Actually, calling applet from javascript behaves as calling unsigned applet (as specified in the jsnote: http://docs.oracle.com/javase/tutorial/deployment/applet/security.html#jsNote. That is fine and is valid when you're using a class you are not allowed to change, but since you're the author of the java class you can always wrap that specific method you need to call from javascript to be executed in the privileged mode, like this:

实际上,从javascript调用applet就像调用unsigned applet一样(在jsnote中指定:http://docs.oracle.com/javase/tutorial/deployment/applet/security.html#jsNote。这很好,当你有效时'使用不允许更改的类,但由于您是java类的作者,因此您始终可以包装需要从javascript调用的特定方法以在特权模式下执行,如下所示:

AccessController.doPrivileged(new PrivilegedAction<String>() {
    @Override
    public String run() {
        exec(command);
        return null;
    }
});

And it should work ok. (This is what is suggested in the upvoted comment by @Jean-Philippe Jodoin but the link provided there is broken)

它应该工作正常。 (这是@ Jean-Philippe Jodoin提出的评论中的建议,但提供的链接已经破了)

#1


The Java 2 security model requires (roughly) that every frame on the stack must be granted a permission for the access control context (acc) to have that permission. JavaScript is on the stack and does not have file access permissions.

Java 2安全模型(大致)要求必须为访问控制上下文(acc)授予堆栈中的每个帧以获得该权限。 JavaScript位于堆栈中,没有文件访问权限。

#2


Solved the problem with, in Java:

用Java解决了这个问题:

exec(getParameter("command"));

and then in JavaScript:

然后在JavaScript中:

<script type="text/javascript">

function exec( command ) {

    var applet = "<applet id='applet' style='visibility: hidden' name='applet' archive='NetAppletLauncher4.jar' code='src.NetsetAppletLauncher' width='20' height='20' MAYSCRIPT ><param name='command' value='" + command + "' />Sorry, you need a Java-enabled browser.</applet>";

    var body = document.getElementsByTagName("body")[0];
    var div = document.createElement("div");
    div.innerHTML = applet;
    body.appendChild(div);

}

</script>

#3


I agree : it is prohibited to manipulate a signed applet from javascript, and the workaround is to rewrite the applet tag in javascript in the page document.

我同意:禁止从javascript操作已签名的applet,解决方法是在页面文档中的javascript中重写applet标记。

I found this source with a bit of theory proving we are right http://docs.oracle.com/javase/tutorial/deployment/applet/security.html#jsNote

我发现这个来源有一些理论证明我们是对的http://docs.oracle.com/javase/tutorial/deployment/applet/security.html#jsNote

#4


Actually, calling applet from javascript behaves as calling unsigned applet (as specified in the jsnote: http://docs.oracle.com/javase/tutorial/deployment/applet/security.html#jsNote. That is fine and is valid when you're using a class you are not allowed to change, but since you're the author of the java class you can always wrap that specific method you need to call from javascript to be executed in the privileged mode, like this:

实际上,从javascript调用applet就像调用unsigned applet一样(在jsnote中指定:http://docs.oracle.com/javase/tutorial/deployment/applet/security.html#jsNote。这很好,当你有效时'使用不允许更改的类,但由于您是java类的作者,因此您始终可以包装需要从javascript调用的特定方法以在特权模式下执行,如下所示:

AccessController.doPrivileged(new PrivilegedAction<String>() {
    @Override
    public String run() {
        exec(command);
        return null;
    }
});

And it should work ok. (This is what is suggested in the upvoted comment by @Jean-Philippe Jodoin but the link provided there is broken)

它应该工作正常。 (这是@ Jean-Philippe Jodoin提出的评论中的建议,但提供的链接已经破了)