Versions Compared

Key

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

Code should only be signed because only if it requires elevated privileges to perform one or more tasks . See rule (see ENV00-J. Do not sign code that performs only unprivileged operations for more information). For example, applets are denied the privilege of making HTTP connections to any hosts except the host from which they came. When an applet requires an HTTP connection with an external host to download plug-ins or extensions, its vendor may provide signed code rather than forcing force the user to arbitrarily assign the permissions it requires. Because executing privilege-elevated signed code can be extremely dangerous, verifying the authenticity of its origin is of utmost importance.

Java-based technologies typically use the Java Archive (JAR) feature to package files for platform-independent deployment. JAR files are the preferred means of distribution for Enterprise Java-Beans (EJB), MIDlets (J2ME), and Weblogic Server J2EE applications, for example. The point-and-click installation provided by Java Web Start also relies on the JAR file format for packaging. Vendors sign their JAR files when required. This Signing certifies the authenticity of the code, but it cannot guarantee the security of the code.

According to the Java Tutorials [Java Tutorials 2008],

If you are creating applet code that you will sign, it needs to be placed in a JAR file. The same is true if you are creating application code that may be similarly restricted by running it with a security manager. The reason you need the JAR file is that when a policy file specifies that code signed by a particular entity is permitted one or more operations, such as specific file reads or writes, the code is expected to come from a signed JAR file. (The term "signed code" is an abbreviated way of saying "code in a class file that appears in a JAR file that was signed.")

...

This noncompliant code example demonstrates the JarRunner application, which can be used to dynamically execute a particular class residing within a JAR file (abridged version of the class in The Java Tutorials [Java Tutorials 2008]). It creates a JarClassLoader that loads an application update, plug-in, or patch over an untrusted network such as the Internet. The URL to fetch the code is specified as the first argument (for example, http://www.securecoding.cert.org/software-updates.jar); any other arguments specify the arguments that are to be passed to the class that is loaded. JarRunner uses reflection to invoke the main() method of the loaded class. Unfortunately, by default, JarClassLoader verifies the signature using the public key contained within the JAR file.

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);
  }
}

final 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", "", 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", 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");
    }
    try {
      m.invoke(null, new Object[] { args });
    } catch (IllegalAccessException e) {
      System.out.println("Access denied");
    }
  }
}

Compliant Solution (jarsigner)

Users can ����������‚�š�š�š�š����������€š�š�š�š�? but can—but usually do not ����������‚�š�š�š�š����������€š�š�š�š�? explicitly not—explicitly check JAR file signatures at the command line. This solution may be an adequate solution for programs that require manual installation of JAR files. Any malicious tampering results in a SecurityException when the jarsigner tool is invoked with the -verify option.

Code Block
bgColor#ccccff

jarsigner -verify signed-updates-jar-file.jar

...

When the local system cannot reliably verify the signature, the invoking program must verify the signature programmatically by obtaining the chain of certificates from the CodeSource of the class being loaded and checking whether any of the certificates belong to a trusted signer whose certificate has been securely obtained beforehand and stored in a local keystore. This compliant solution demonstrates the necessary modifications to the invokeClass() method.:

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) {
    // returnReturn, do not execute if unsigned
    System.out.println("No signature!");
    return;  
  }  

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

...

The URLClassLoader and all its subclasses are given by default only enough permissions to interact with the URL that was specified when the URLClassLoader object was created. This , which means that the loaded code can interact only with the specified host. This It fails to mitigate the risk completely, however, because the loaded code may have been granted privileges that permit other sensitive operations such as updating an existing local JAR file.

...

Failure to verify a digital signature, whether manually or programmatically, can result in the execution of malicious code.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

SEC06-J

high

High

probable

Probable

medium

Medium

P12

L1

Automated Detection

Automated detection is not feasible in the fully general case. However, an approach similar to Design Fragments [Fairbanks 2007] could assist both programmers and static analysis tools.

ToolVersionCheckerDescription
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

JAVA.IO.INJ.ANDROID.MESSAGE
JAVA.IO.TAINT.MESSAGE

Android Message Injection (Java)
Tainted Message (Java)

Related Guidelines

ISO/IEC TR 24772:2010

Improperly Verified Signature [XZR]

MITRE CWE

CWE-300

.

, Channel

accessible

Accessible by

non

Non-endpoint (aka "

man

Man-in-the-

middle

Middle")

 

CWE-319

.

, Cleartext

transmission  

Transmission of

sensitive information

Sensitive Information
CWE-347, Improper Verification of Cryptographic Signature


CWE-494

.

, Download of

code without integrity check

 

CWE-347. Improper verification of cryptographic signature

Code without Integrity Check

Bibliography

[API

2006

2014]

 


[Bea 2008]

 


[Eclipse 2008]

JAR Signing

and


Signed

bundles

Bundles and

protecting

Protecting against

malicious code

Malicious Code

[Fairbanks 2007]

 


[Flanagan 2005]

Chapter 24, "The java.util.jar Package"

[Gong 2003]

Section 12.8.3, "jarsigner"

[Halloway 2001]

 


[JarSpec 2008]

Signature Validation

[

Oaks 2001]

Chapter 12, Digital Signatures, Signed Classes

[Muchow 2001]

 

[Tutorials 2008

Java Tutorials]

The JarRunner Class

,


Lesson: API and Tools Use for Secure Code and File Exchanges

and


Verifying Signed JAR Files

[Muchow 2001]

[Oaks 2001]

Chapter 12, "Digital Signatures, Signed Classes"


...

Image Added Image Added Image Removed      14. Platform Security (SEC)      Image Modified