3 Replies Latest reply: Oct 16, 2012 1:59 PM by 854422 RSS

    Access Control Issues with fully signed code.

    968121
      java.lang.reflect.InvocationTargetException
           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 com.ephemeral.vigil.loader.JarClassLoader.invokeClass(JarClassLoader.java:44)
           at com.ephemeral.vigil.loader.VigilLoader.main(VigilLoader.java:38)
           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 com.sun.javaws.Launcher.executeApplication(Unknown Source)
           at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
           at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
           at com.sun.javaws.Launcher.run(Unknown Source)
           at java.lang.Thread.run(Unknown Source)
      Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "user.home" "read")
           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.checkPropertyAccess(Unknown Source)
           at java.lang.System.getProperty(Unknown Source)
           at com.ephemeral.vigil.ClientLauncher.main(SourceFile:48)
           ... 15 more


      So I am trying to write a sort of 'fix' for the fact that JNLP is for lack of a better word, a shitheap; what I did was wrote a simple little non-changing jnlp application that downloads the most recent binary and then reflectively loads it; and while this works fine in eclipse tests (as I assume it isn't using any sort of access control manager that is restrictive) it outright fails in my server tests because it seems to think that the code loaded from the external .jar isn't trusted, when in fact it is as I've signed both of them with a signature, I've even tried a securitymanager override that just allows everything in the short span of executing the external jar's function.
        • 1. Re: Access Control Issues with fully signed code.
          sabre150
          >
          <snip/>
          So I am trying to write a sort of 'fix' for the fact that JNLP is for lack of a better word, a shitheap;
          Of course we don't know what aspects you consider to be "a shitheap" but my bet is that you consider it as such because it does not have some obscure functionality you need rather than because of a bug. Maybe if you explained what functionality you need then someone might be able to suggest an approach.
          what I did was wrote a simple little non-changing jnlp application that downloads the most recent binary and then reflectively loads it; and while this works fine in eclipse tests (as I assume it isn't using any sort of access control manager that is restrictive) it outright fails in my server tests because it seems to think that the code loaded from the external .jar isn't trusted, when in fact it is as I've signed both of them with a signature, I've even tried a securitymanager override that just allows everything in the short span of executing the external jar's function.
          Without any view of your code or your build procedure we are stuffed. I for one am not going to try to re-create your problem without significant further detail from you. I could suggest that you to create and post the two programs (master and slave) and the build system of an SSCCE that illustrates the problem but from the tone of your post ( entering the forum all guns blazing with your first post ) I suspect you are just wanting to gripe.
          • 2. Re: Access Control Issues with fully signed code.
            968121
            I consider it to be a shitheap because it never actually updates the binaries correctly. EVER.

            Not with versioning
            Not with timestamping.


            Also, here's the loader code.

            package com.ephemeral.vigil.loader;

            import java.io.BufferedReader;
            import java.io.File;
            import java.io.FileOutputStream;
            import java.io.IOException;
            import java.io.InputStreamReader;
            import java.lang.reflect.InvocationTargetException;
            import java.net.HttpURLConnection;
            import java.net.MalformedURLException;
            import java.net.URL;
            import java.nio.channels.Channels;
            import java.nio.channels.ReadableByteChannel;
            import java.security.AccessController;
            import java.security.PrivilegedAction;

            public final class VigilLoader
            {
                 private static String SERVER_BASE_URL = "http://dev.ephemeraldevelopment.com/vigil";
                 private static String SERVER_BINARIES_PATH = SERVER_BASE_URL + "/bin";
                 
                 private static String BASE_PATH;
                 private static String TARGET_BINARY;
                 
                 private static JarClassLoader JCL;

                 public static void main(final String[] args)
                 {
                      BASE_PATH = "C:\\Users\\Gregory Hlavac\\" + "Vigil";
                      TARGET_BINARY = getResponse(SERVER_BASE_URL + "/version.php");
                      
                      
                      checkCreateStructure();
                      
                      checkOrGetBinary();
                      

                           AccessController.doPrivileged(new PrivilegedAction<Object>()
                           {
                                @Override
                                public Object run()
                                {
                                     try
                                     {
                                          SecurityManager old = System.getSecurityManager();
                                          
                                          UnchainedSecurityManager usm = new UnchainedSecurityManager();
                                          
                                          System.setSecurityManager(usm);

                                          JCL.invokeClass(JCL.getMainClassName(), args);          
                                          
                                          //System.setSecurityManager(old);
                                     }
                                     catch (ClassNotFoundException e)
                                     {
                                          // TODO Auto-generated catch block
                                          e.printStackTrace();
                                     }
                                     catch (NoSuchMethodException e)
                                     {
                                          // TODO Auto-generated catch block
                                          e.printStackTrace();
                                     }
                                     catch (InvocationTargetException e)
                                     {
                                          // TODO Auto-generated catch block
                                          e.printStackTrace();
                                     }
                                     catch (IOException e)
                                     {
                                          // TODO Auto-generated catch block
                                          e.printStackTrace();
                                     }
                                     return args;
                                }
                           });
                      
                      /*
                 Class<?> cls;
                      try
                      {
                           JarClassLoader cl = new JarClassLoader(url);
                           
                           cls = Class.forName("com.ephemeral.vigil.ClientLauncher");
                      Method meth = cls.getMethod("main", String[].class);
                      String[] params = null;
                      meth.invoke(null, (Object) params);
                      }
                      catch (ClassNotFoundException e)
                      {
                           // TODO Auto-generated catch block
                           e.printStackTrace();
                      }
                      catch (IllegalArgumentException e)
                      {
                           // TODO Auto-generated catch block
                           e.printStackTrace();
                      }
                      catch (IllegalAccessException e)
                      {
                           // TODO Auto-generated catch block
                           e.printStackTrace();
                      }
                      catch (InvocationTargetException e)
                      {
                           // TODO Auto-generated catch block
                           e.printStackTrace();
                      }
                      catch (SecurityException e)
                      {
                           // TODO Auto-generated catch block
                           e.printStackTrace();
                      }
                      catch (NoSuchMethodException e)
                      {
                           // TODO Auto-generated catch block
                           e.printStackTrace();
                      }*/
                 }
                 
                 private static void checkOrGetBinary()
                 {
                      File vigilBinary = new File(BASE_PATH + System.getProperty("file.separator") + TARGET_BINARY);
                      
                      if(!vigilBinary.exists())
                      {
                           downloadFile(SERVER_BINARIES_PATH + "/" + TARGET_BINARY, vigilBinary);
                      }
                           
                      try
                      {
                           JCL = new JarClassLoader(vigilBinary.toURL());
                      }
                      catch (MalformedURLException e)
                      {
                           // TODO Auto-generated catch block
                           e.printStackTrace();
                      }
                      
                      /*
                      try
                      {
                           ReflectionHacker.addUrlToClassLoader(vigilBinary);
                      }
                      catch (MalformedURLException e)
                      {
                           // TODO Auto-generated catch block
                           e.printStackTrace();
                      }
                      catch (IOException e)
                      {
                           // TODO Auto-generated catch block
                           e.printStackTrace();
                      }
                      */
                 }
                 
                 private static void checkCreateStructure()
                 {
                      File vigilFolder = new File(BASE_PATH, "lib");
                      
                      vigilFolder.mkdirs();
                 }
                 
                 
                 private static void downloadFile(String from, File to)
                 {
                      try
                      {
                           URL website = new URL(from);
                      ReadableByteChannel rbc = Channels.newChannel(website.openStream());
                      FileOutputStream fos = new FileOutputStream(to);
                      fos.getChannel().transferFrom(rbc, 0, 1 << 24);
                      
                      fos.close();
                      }
                      catch(IOException iox)
                      {
                           
                      }
                 }
                 
                 public static String getResponse(String urlToRead)
                 {
                 URL url;
                 HttpURLConnection conn;
                 BufferedReader rd;
                 String line;
                 String result = "";
                 try
                 {
                                url = new URL(urlToRead);
                      conn = (HttpURLConnection) url.openConnection();
                      conn.setRequestMethod("GET");
                      rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                      while ((line = rd.readLine()) != null)
                      {
                           result += line;
                      }
                      rd.close();
                 }
                 catch (Exception e)
                 {
                 e.printStackTrace();
                 }
                 return result;
                 }
            }

            Edited by: 965118 on Oct 13, 2012 10:08 AM

            public class UnchainedSecurityManager extends SecurityManager
            {
            @Override
            public void checkPermission(Permission perm)
            {
            check(perm);
            }

            @Override
            public void checkPermission(Permission perm, Object context)
            {
            check(perm);
            }

            private void check(Permission perm)
            {
            return;
            }
            }

            Edited by: 965118 on Oct 13, 2012 10:11 AM
            • 3. Re: Access Control Issues with fully signed code.
              854422
              I have built a shell Android application which does the same thing. My implementation looks very different from yours, which is not completely unexpected. I thought I would warn you though, that even if you got this working, you have given malicious hacker multiple openings.

              First, your url is using http, not https. This is not fatal, if you close the 2nd flaw, but better to have both a belt and suspenders.

              2nd, you do not verify that all files in the downloaded JAR file are signed using the same certificate as the one that signed the jnlp app. I am not going to provide code to do this. Look at java.util.jar.JarFile & JarEntry for clues. JarClassLoader might check for valid sigs. Problem is all the hacker has to do is sign with anything.

              I really think you are better off reporting your problems using a conventional approach.