...
The default automatic signature verification process may still be used, but is not sufficient. Systems that use the default automatic signature verification process must perform additional checks to ensure that the signature is correct (such as comparing it against a known trusted signature).
Noncompliant Code Example
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 [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 | ||
---|---|---|
| ||
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 usually do not — explicitly check JAR file signatures at the command line; this 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 | ||
---|---|---|
| ||
jarsigner -verify signed-updates-jar-file.jar |
Compliant Solution (certificate chain)
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 belongs 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.
...
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 means that the loaded code can interact only with the specified host. This fails to mitigate the risk completely, however, as the loaded code may have been granted privileges that permit other sensitive operations such as updating an existing local JAR file.
Risk Assessment
Failure to verify a digital signature, whether manually or programmatically, can lead to the execution of malicious code.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
SEC09 SEC06-J | high | probable | medium | P12 | L1 |
Automated Detection
Wiki Markup |
---|
Automated detection is not feasible in the fully general case. However, an approach similar to Design Fragments \[[Fairbanks 07|AA. Bibliography#Fairbanks 07]\] could assist both programmers and static analysis tools. |
Related Guidelines
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="00d277c68d1c2aff-e330b0eb-457245c2-926caf03-f651c2a1ae78898baf12a4e4"><ac:plain-text-body><![CDATA[ | [ISO/IEC TR 24772:2010 | http://www.aitcnet.org/isai/] | "Improperly Verified Signature [XZR]" | ]]></ac:plain-text-body></ac:structured-macro> |
CWE ID 300, "Channel Accessible by Non-Endpoint (aka 'Man-in-the-Middle')" | ||||
| CWE ID 319, "Cleartext Transmission of Sensitive Information" | |||
| CWE ID 494, "Download of Code Without Integrity Check" | |||
| CWE ID 347, "Improper Verification of Cryptographic Signature" |
Bibliography
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="73a46a854914e7d9-0c0218f3-488541aa-a5d9ac6e-3050485ef5e52efb68558c75"><ac:plain-text-body><![CDATA[ | [[API 2006 | AA. Bibliography#API 06]] |
| ]]></ac:plain-text-body></ac:structured-macro> | |||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="cfd09858d0f5a04d-5b3cddbe-45b54d70-9532ba31-03f0aaa0b010cd024b0b97d6"><ac:plain-text-body><![CDATA[ | [[Bea 2008 | AA. Bibliography#Bea 08]] |
| ]]></ac:plain-text-body></ac:structured-macro> | |||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="b1d17190d8b0f6ea-4f7b0525-421840d6-842e958c-f1e98665e6fcec819b116149"><ac:plain-text-body><![CDATA[ | [[Eclipse 2008 | AA. Bibliography#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] | ]]></ac:plain-text-body></ac:structured-macro> | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="50553bc3f28d5c01-b84a321d-42c24ddc-9155ac23-d438b09e0adc05deb4d7eeec"><ac:plain-text-body><![CDATA[ | [[Fairbanks 07 | AA. Bibliography#Fairbanks 07]] |
| ]]></ac:plain-text-body></ac:structured-macro> | |||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="0a921d97d48c8610-fed9663a-4c8c4ae0-9efd81f1-20281da39b43a6dfeff070c6"><ac:plain-text-body><![CDATA[ | [[Flanagan 2005 | AA. Bibliography#Flanagan 05]] | Chapter 24. The java.util.jar Package | ]]></ac:plain-text-body></ac:structured-macro> | |||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="12ce19d3ecb211d1-7f15cf00-40374c0f-9e53aa53-eb5b241acf2e37885221dde8"><ac:plain-text-body><![CDATA[ | [[Gong 2003 | AA. Bibliography#Gong 03]] | 12.8.3 jarsigner | ]]></ac:plain-text-body></ac:structured-macro> | |||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="51cd3158d753fe1e-523ed85f-45ae4d8e-91aa93d3-221c0ef26b17280c2ddcef62"><ac:plain-text-body><![CDATA[ | [[Halloway 2001 | AA. Bibliography#Halloway 01]] |
| ]]></ac:plain-text-body></ac:structured-macro> | |||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="65c0b3ab9ae36e4e-b1cbf874-48a34c3a-8db0a8f6-dddae89b04ffce5d4fdcf910"><ac:plain-text-body><![CDATA[ | [[JarSpec 2008 | AA. Bibliography#JarSpec 08]] | Signature Validation |
| ]]></ac:plain-text-body></ac:structured-macro> | ||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="feac63eb2219b9c8-1fdbe285-42e442ab-8960bd61-9136fc174e71bea504dcc9dd"><ac:plain-text-body><![CDATA[ | [[Oaks 2001 | AA. Bibliography#Oaks 01]] | Chapter 12: Digital Signatures, Signed Classes | ]]></ac:plain-text-body></ac:structured-macro> | |||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="ccacf6052b4de586-a9169617-49924f57-aa8b8dd3-ba67bb3ca7fcba197e8c4301"><ac:plain-text-body><![CDATA[ | [[Muchow 2001 | AA. Bibliography#Muchow 01]] |
| ]]></ac:plain-text-body></ac:structured-macro> | |||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="9c784b0055969b0e-1462cf66-4d1f4bcd-836184ef-821c2dd4309562d5e81c58b4"><ac:plain-text-body><![CDATA[ | [[Tutorials 2008 | AA. Bibliography#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] | ]]></ac:plain-text-body></ac:structured-macro> |
...