3

I have a question/problem related to Java Applet security...
I use the Applet that has to take files from server (ASP.NET) and represent the information from it. Applet take files using the code:

URL u = new URL(getCodeBase(), filename);
BufferedReader d = new BufferedReader(new InputStreamReader(u.openStream()));

This code appears in two places:

  1. Init() method
  2. Some another method Test() that called manually from JavaScript

So, when I try to load the page with Applet using the URL http://127.0.0.1:8000/Test.aspx, everything works fine and I can read file content from both methods. But if I change the URL on http://localhost:8000/, only the first method works properly and I can get files content and for the second one I get the next error message in JavaConsole:

java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:8000 connect,resolve)

What it the difference in this case? Why 'localhost' is impossible in this case? Is there any way how to grant access to 'localhost' the same as 127.0.0.1?

here is simplest applet's example:

public class TestApplet extends Applet {

    public void init()
    {
        System.out.println( "init...");

        readDocument();
    }

    public void readDocument()
    {
        System.out.println( "read test.txt file...");

        URL base = getCodeBase();
        String filename = "test.txt";
        try {
            URL u = new URL(base, filename);
            BufferedReader d = new BufferedReader(new InputStreamReader(u.openStream()));
            System.out.println(d.readLine());
            System.out.println("Done!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

and next code used on the client side:

<applet archive="/Content/test.jar" code="test.TestApplet.class" name="testApplet" mayscript></applet>

<script language="javascript" type="text/javascript">
    $(document).ready(function () {
        var testApplet = document.testApplet;
        testApplet.readDocument();
    });
</script>

this code works perfectly when I try to use http://127.0.0.1:8000/Test.aspx and doesn't work when I user http://localhost:8000/Test.aspx. I java console I see the next:

init...
read test.txt file...
some text...
Done!
read test.txt file...
java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:8000 connect,resolve)
    at java.security.AccessControlContext.checkPermission(Unknown Source)
    at java.security.AccessController.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkConnect(Unknown Source)
    at sun.plugin2.applet.Applet2SecurityManager.checkConnect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at sun.net.NetworkClient.doConnect(Unknown Source)
    at sun.net.www.http.HttpClient.openServer(Unknown Source)
    at sun.net.www.http.HttpClient.openServer(Unknown Source)
    at sun.net.www.http.HttpClient.<init>(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at java.net.URL.openStream(Unknown Source)
    at test.TestApplet.readDocument(TestApplet.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.plugin.javascript.JSInvoke.invoke(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source)
    at sun.plugin2.liveconnect.JavaClass$MethodInfo.invoke(Unknown Source)
    at sun.plugin2.liveconnect.JavaClass$MemberBundle.invoke(Unknown Source)
    at sun.plugin2.liveconnect.JavaClass.invoke0(Unknown Source)
    at sun.plugin2.liveconnect.JavaClass.invoke(Unknown Source)
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$DefaultInvocationDelegate.invoke(Unknown Source)
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo.doObjectOp(Unknown Source)
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$LiveConnectWorker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

P.S.: Applet is signed.

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
Mr. Pumpkin
  • 6,212
  • 6
  • 44
  • 60
  • in both cases you access "127.0.0.1", I don't see where you call "localhost", or have a problem with localhost... – woliveirajr Jul 04 '11 at 14:36
  • How does the javascript invoke the `Test` method? How does it create the URL? Can you ensure it uses the same URL as the Applet does in the browser? – ewan.chalmers Jul 04 '11 at 14:38
  • yes... misspelling... changed – Mr. Pumpkin Jul 04 '11 at 14:42
  • Maybe you could post some more code so we can see what's happening. – carlspring Jul 04 '11 at 14:47
  • in both cases getCodeBase() returns "http://127.0.0.1:8000". I suspect that it can be the problem but have no idea why it returns it as "http://127.0.0.1:8000" when the page URL starts with "http://localhost:8000/" – Mr. Pumpkin Jul 04 '11 at 14:51
  • And if you try http://localhost:8000/Test.aspx and http://127.0.0.1:8000/ , does it make difference ? – woliveirajr Jul 04 '11 at 19:19
  • Yes, it works when I use http://127.0.0.1:8000/Test.aspx and doesn't work when I use http://localhost:8000/Test.aspx – Mr. Pumpkin Jul 04 '11 at 20:03
  • @Aleksey : And if do a System.out.println() just after the "URL base = ...." and "URL u = ...", what are the contents of `base` and `u` ? – woliveirajr Jul 05 '11 at 11:37

3 Answers3

3

The problem is the call from JavaScript. If you are using JavaScript to call your method, the permissions of the call get down to the intersection of the JavaScript bridge's permissions (i.e. nothing) and the permissions of your own code - even if your own code is signed.

To avoid this, and use the full privileges of your applet's code, put the security-relevant parts inside a AccessController.doPrivileged(...) call. (Of course, your applet should first check that this can't do anything malicious.)

I have no idea why it works if you are using the IP address directly instead of localhost, though.

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
  • Thanks a lot! It worked!!! Unfortunately don't have enough reputation to mark this response as useful... will do when have enough. Thanks again! – Mr. Pumpkin Jul 05 '11 at 18:48
  • @Aleksey: As the one who asked this question, you can *accept* the answer you see as most useful for you, by using the accept button (this checkmark sign: ✔) beside the answer. – Paŭlo Ebermann Jul 05 '11 at 20:02
2

localhost is an alias for 127.0.0.1 so you may have to set/fix it in your enviroment. Under Windows you have to edit the file C:\Windows\System32\drivers\etc\hosts.

ascanio
  • 1,506
  • 1
  • 9
  • 18
  • I thought about it... have "127.0.0.1 localhost" in hosts file. Doesn't help. – Mr. Pumpkin Jul 04 '11 at 14:40
  • @Aleksey I googled a bit, and found this http://stackoverflow.com/questions/2612895/where-to-place-java-applet-policy-file and this http://imagej.588099.n2.nabble.com/appletviewer-imageJA-trouble-td5943534.html hope it helps – ascanio Jul 04 '11 at 14:59
  • I googled it a lot... I spent all my weekend on it... here is my another post about your suggestion: http://www.java-forums.org/java-applets/45977-how-grant-allpermission-applet.html. .java.policy is not working in this case. – Mr. Pumpkin Jul 04 '11 at 15:27
0

localhost is typically resolved to both ::1 and 127.0.0.1 and the OS/libc is usually set up so that IPv6 is preferred in these circumstances.

Therefore, it's likely you're allowing only 127.0.0.1 and not IPv6 connections from ::1.

Artefacto
  • 96,375
  • 17
  • 202
  • 225
  • not sure that understood correctly what are you talking about... but I have next couple lines commented out in hosts file: 127.0.0.1 localhost ::1 localhost – Mr. Pumpkin Jul 04 '11 at 14:47