Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Edited by NavBot

...

Code Block
bgColor#FFcccc
public class JarRunner {
  public static void main(String[] args) throws IOException, 
    ClassNotFoundException,NoSuchMethodException, InvocationTargetException {
  
    URL url = new URL(args[0]);
    
    // Create the class loader for the application jar file
    JarClassLoader cl = new JarClassLoader(url);
    
    // Get the application's main class name
    String name = cl.getMainClassName();
    
    // Get arguments for the application
    String[] newArgs = new String[args.length - 1];
    System.arraycopy(args, 1, newArgs, 0, newArgs.length);
    
    // Invoke application's main class
    cl.invokeClass(name, newArgs);
  }
}

class JarClassLoader extends URLClassLoader {
  private URL url;
  public JarClassLoader(URL url) {
    super(new URL[] { url });
    this.url = url;
  }

  public String getMainClassName() throws IOException {
    URL u = new URL("jar", """jar", "", url + ""!/"");
    JarURLConnection uc = (JarURLConnection) u.openConnection();
    Attributes attr = uc.getMainAttributes();
    return attr != null ? attr.getValue(Attributes.Name.MAIN_CLASS) : null;
  }

  public void invokeClass(String name, String[] args)
      throws ClassNotFoundException, NoSuchMethodException,
      InvocationTargetException {
    Class c = loadClass(name);
    Method m = c.getMethod("main""main", new Class[] { args.getClass() });
    m.setAccessible(true);
    int mods = m.getModifiers();
    if (m.getReturnType() != void.class || !Modifier.isStatic(mods)
        || !Modifier.isPublic(mods)) { throw new NoSuchMethodException("main""main"); }
    try {
      m.invoke(null, new Object[] { args });
    } catch (IllegalAccessException e) { System.out.println(""Access denied""); }
  }
}

Compliant Solution

...

Code Block
bgColor#ccccff
public void invokeClass(String name, String[] args)
    throws ClassNotFoundException, NoSuchMethodException, 
    InvocationTargetException, GeneralSecurityException, IOException {
  Class c = loadClass(name);
  Certificate[] certs = c.getProtectionDomain().getCodeSource().getCertificates();
  if(certs == null) {
    System.out.println(""No signature!""); return;  // return, do not execute if unsigned
  }  

  KeyStore ks = KeyStore.getInstance("JKS""JKS");
  ks.load(new FileInputStream(System.getProperty(""user.home""+ File.separator + ""keystore.jks"")),
    "loadkeystorepassword""loadkeystorepassword".toCharArray());
  Certificate pubCert = ks.getCertificate("user""user");  // user is the alias
  certs[0].verify(pubCert.getPublicKey()); // check with the trusted public key, else throws exception
}

...

Wiki Markup
\[[API 06|AA. Java References#API 06]\] 
\[[Gong 03|AA. Java References#Gong 03]\] 12.8.3 jarsigner
\[[Eclipse 08|AA. Java References#Eclipse 08]\] [JAR Signing|http://wiki.eclipse.org/JAR_Signing] and [Signed bundles and protecting against malicious code|http://help.eclipse.org/stable/index.jsp?topic=/org.eclipse.platform.doc.isv/guide]
\[[Halloway 01|AA. Java References#Halloway 01]\] 
\[[Flanagan 05|AA. Java References#Flanagan 05]\] Chapter 24. The java.util.jar Package
\[[Oaks 01|AA. Java References#Oaks 01]\] Chapter 12: Digital Signatures, Signed Classes
\[[Tutorials 08|AA. Java References#Tutorials 08]\] [The JarRunner Class|http://java.sun.com/docs/books/tutorial/deployment/jar/jarrunner.html], [Lesson: API and Tools Use for Secure Code and File Exchanges|http://java.sun.com/docs/books/tutorial/security/sigcert/index.html] and [Verifying Signed JAR Files|http://java.sun.com/docs/books/tutorial/deployment/jar/verify.html]
\[[JarSpec 08|AA. Java References#JarSpec 08]\] Signature Validation 
\[[Bea 08|AA. Java References#Bea 08]\] 
\[[Muchow 01|AA. Java References#Muchow 01]\] 
\[[MITRE 09|AA. Java References#MITRE 09]\] [CWE ID 300|http://cwe.mitre.org/data/definitions/300.html] ""Channel Accessible by Non-Endpoint (aka 'Man-in-the-Middle')"", [CWE ID 319|http://cwe.mitre.org/data/definitions/319.html] ""Cleartext Transmission of Sensitive Information"", [CWE ID 494|http://cwe.mitre.org/data/definitions/494.html] ""Download of Code Without Integrity Check"", [CWE ID 347|http://cwe.mitre.org/data/definitions/347.html] ""Improperly Verified Signature""

...

SEC03-J. Do not use APIs that perform access checks against the immediate caller            02. Platform Security (SEC)            SEC05-J. Minimize accessibility of classes and their members