Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6756165

Unsigned applet cannot connect back to origin host when Proxy is used in browser

    XMLWordPrintable

Details

    • 6u4
    • x86
    • windows_xp

    Description

      FULL PRODUCT VERSION :
      java version "1.6.0_07"
      Java(TM) SE Runtime Environment (build 1.6.0_07-b06)
      Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      OS independant (tested on Linux 2.6.24, and Windows XP SP3)

      A DESCRIPTION OF THE PROBLEM :
      Unsigned applets cannot connect back via Socket to the originating host (from codebase) when a Proxy is configured in user's browser (IE7/IE6//FF3/FF2 tested) and when origin host's IP address doesn't resolve back to the same hostname.

      Example:
      www.hostingsite.com resolves to 1.2.3.4
      but, 1.2.3.4 resolves back to 4.3.2.1-somewebhost.com

      Affects JRE versions 1.6.0_03 - 1.6.0_07
      This wasn't a problem in 1.6.0_02 or prior versions according to my tests.

      An AccessControlException is thrown about SocketPermission:

      I believe the security manager is doing unnecessary lookups, even after the resolved IP matches to the IP of the origin host. This is apparent from the fairly long delay before the ACE is thrown about SocketPermission.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Configure HTTP Proxy in browser (IE/Firefox)
      2. visit an html page that embeds a simple applet that tries to connect back to origin host whose hostname resolves to an IP address but the IP address resolves to a different hostname. (example code below)


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Applet should be able to connect back to originating host via Socket connection or write (post) to a URL on origin host (which requires a new Socket connection back)
      ACTUAL -
      Socket sock = new Socket(Proxy.NO_PROXY);
      InetSocketAddress sockAddress = new InetSocketAddress(getCodeBase().getHost(), port);
      sock.connect(sockAddress);

      The above snippet of code would throw an ACE about SocketPermission when applet tries to initiate sock.connect

      Moreover,

      URL urlRequest = new URL(this.getCodeBase()+path);
      HttpURLConnection conn = (HttpURLConnection)urlRequest.openConnection(Proxy.NO_PROXY);
      conn.getOutputStream();

      would also throw an ACE about SocketPermission when the applet tries to initiate Socket connection for the conn.getOutputStream() call.


      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.security.AccessControlException: access denied (java.net.SocketPermission x.x.x.x:80 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 java.net.Socket.connect(Unknown Source)
      at java.net.Socket.connect(Unknown Source)
      at java.net.Socket.<init>(Unknown Source)
      at java.net.Socket.<init>(Unknown Source)
      at HttpRequestor.start(HttpRequestor.java:16)
      at sun.applet.AppletPanel.run(Unknown Source)
      at java.lang.Thread.run(Unknown Source)

      x.x.x.x being the resolved IP address of the origin server

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.applet.*;
      import java.net.*;

      public class HttpRequestor extends Applet
      {
      public void start()
      {
      try
      {
      Socket sock = new Socket(Proxy.NO_PROXY);
      InetSocketAddress sockAddress = new InetSocketAddress(getCodeBase().getHost(), Integer.parseInt(getParameter("port")));
      sock.connect(sockAddress);

      String path = getParameter("path")+"&local="+sock.getLocalAddress().getHostAddress();
      String httpRequest = "GET "+path+" HTTP/1.0\r\nHost: "+getCodeBase().getHost()+"\r\n\r\n";
      sock.getOutputStream().write(httpRequest.getBytes());
      sock.getInputStream();
      }
      catch (Exception e)
      {
      e.printStackTrace();
      }
      }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      The only possible workaround I could find is if the the applet can be loaded from IP-address in the codebase URL to avoid the unnecessary lookups by the SecurityManger.

      This, however, maybe very difficult to use in most virtual-hosting environment, and IE browsers older than IE7 would most likely throw an error like "Class not found".

      Example, if www.hostingsite.com resolves to 1.2.3.4
      and http://1.2.3.4 goes to http://www.hostingsite.com

      Change the codebase URL in the html embedding the applet, from:
      "http://www.hostingsite.com/classes"
      to:
      "http://1.2.3.4/classes"

      Release Regression From : 6u2
      The above release value was the last known release where this
      bug was not reproducible. Since then there has been a regression.

      Attachments

        Activity

          People

            cbensen Chris Bensen (Inactive)
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: