Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

When the local system cannot be trusted, an explicit signature verification check must be built within the invoking program. This can be achieved by obtaining the chain of certificates from the CodeSource of the class being loaded and checking if any one of the certificates belongs to the trusted signer whose certificate has been obtained securely beforehand and stored in a local keystore. The invokeClass method can be modified to do this as shown in this 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");
  ks.load(new FileInputStream(System.getProperty("user.home"+ File.separator + "keystore.jks")),
    "loadkeystorepassword".toCharArray());
  Certificate pubCert = ks.getCertificate("user");  // user is the alias
  certs[0].verify(pubCert.getPublicKey()); // check with the trusted public key, else throws exception
}

(Note that invokeClass now has two more exceptions in its throws clause, so the catch block in the main method must be altered accordingly.)

It is not always the case that arbitrary code gets executed. By default, the URLClassLoader and all its subclasses are only given enough permissions to interact with the URL that was specified when the URLClassLoader object was created. This means that the program can only interact with the specified host. However, this does not mitigate the risk completely as the loaded file may be granted appropriate privileges to perform more sensitive operations such as updating an existing local JAR file.

...