...
Conversely, the assumption that two classes deriving from the same code base are themselves the same is error-prone. While this assumption is commonly observed to be true in desktop applications, it is typically not the case with J2EE servlet containers. The containers can use different class loader instances to deploy and recall applications at runtime, without having to restart the JVM. In such situations, two objects whose classes come from the same code base could appear to the JVM to be two different classes. Also note that the equals()
method might not return true
when comparing objects originating from the same code base.
Noncompliant Code Example
This noncompliant code example compares the name of the class (Auth
) of object auth
to the string "com.application.auth.DefaultAuthenticationHandler"
and branches on the result of the comparison.
...
Comparing fully qualified class names is insufficient because distinct class loaders can load differing classes with identical fully qualified names into a single JVM.
Compliant Solution
This compliant solution compares the class object of class Auth
to the class object of the class that the current class loader loads, instead of comparing just the class names.
...
The call to loadClass()
returns the class with the specified name in the current name space (consisting of the class name and the defining class loader), and the comparison is correctly performed on the two class objects.
Noncompliant Code Example
This noncompliant code example compares the names of the class objects of classes x
and y
using the equals()
method. Again, it is possible that x
and y
are distinct classes with the same name, if they come from different class loaders.
Code Block | ||
---|---|---|
| ||
// Determine whether objects x and y have the same class name if (x.getClass().getName().equals(y.getClass().getName())) { // Code assumes that the objects have the same class } |
Compliant Solution
This compliant solution correctly compares the two objects' classes.
Code Block | ||
---|---|---|
| ||
// Determine whether objects x and y have the same class if (x.getClass() == y.getClass()) { // Code determines whether the objects have the same class } |
Risk Assessment
Comparing classes solely using their names can allow a malicious class to bypass security checks and gain access to protected resources.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
OBJ12 OBJ09-J | high | unlikely | low | P9 | L2 |
Related Guidelines
Bibliography
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="d081c8287e64809b-859ea636-43b04089-806499db-ec721b395d5a17cdedfefeec"><ac:plain-text-body><![CDATA[ | [[Christudas 2005 | AA. Bibliography#Christudas 05]] | Internals of Java Class Loading | ]]></ac:plain-text-body></ac:structured-macro> | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="a7e4f3578e519259-737ce933-45c941e2-81798d94-492edabe86f00fae05b71baa"><ac:plain-text-body><![CDATA[ | [[JVMSpec 1999 | AA. Bibliography#JVMSpec 99]] | [§2.8.1 Class Names | http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html] | ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="1563a4980a45b906-5689e3d1-4d384f6f-ba18b144-95d95d1432779fd076f4fcae"><ac:plain-text-body><![CDATA[ | [[McGraw 1998 | AA. Bibliography#Mcgraw 98]] | Twelve rules for developing more secure Java code | ]]></ac:plain-text-body></ac:structured-macro> | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="bd9a0f4fc2b3c664-22fe9ef7-4af440d3-a4928eea-15549ba7c31f173509a9eeb7"><ac:plain-text-body><![CDATA[ | [[Wheeler 2003 | AA. Bibliography#Wheeler 03]] | [Java | http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/java.html] Secure programming for Linux and Unix HOWTO | ]]></ac:plain-text-body></ac:structured-macro> |
...