In a Java Virtual Machine (JVM), "Two classes are the same class (and consequently the same type) if they are loaded by the same class loader , and they have the same fully qualified name" [JVMSpec 1999]. Two classes with the same name but different package names are distinct, as are two classes with the same fully qualified name loaded by different class loaders.
...
Conversely, the assumption that two classes deriving from the same code base codebase are the same is error prone. While Although 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 codebase 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 basecodebase.
Noncompliant Code Example
This noncompliant code example compares the name of the class of object auth
to the string "com.application.auth.DefaultAuthenticationHandler"
and branches on the result of the comparison.:
Code Block | ||
---|---|---|
| ||
// Determine whether object auth has required/expected class object if (auth.getClass().getName().equals( "com.application.auth.DefaultAuthenticationHandler")) { // ... } |
...
This compliant solution compares the class object auth
to the class object for the canonical default authentication handler.:
Code Block | ||
---|---|---|
| ||
// Determine whether object auth has required/expected class name if (auth.getClass() == com.application.auth.DefaultAuthenticationHandler.class) { // ... } |
The right-hand - side of the comparison directly names the class of the canonical authentication handler. In the event that the canonical authentication handler had not yet been loaded, the Java runtime manages the process of loading the class. Finally, the comparison is correctly performed on the two class objects.
...
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()) { // Objects have the same class } |
...
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 |
---|---|---|---|---|---|
OBJ09-J | High | Unlikely | Low | P9 | L2 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
The Checker Framework |
| Signature String Checker | Ensure that the string representation of a type is properly used for example in Class.forName (see Chapter 13) | ||||||
Parasoft Jtest |
| CERT.OBJ09.CMP | Do not compare Class objects by name | ||||||
PVS-Studio |
| V6054 | |||||||
SonarQube |
| S1872 | Classes should not be compared by name |
Related Guidelines
Bibliography
Internals of Java Class Loading | |
"Twelve |
Rules for Developing More Secure Java Code" | |
...
04. Object Orientation (OBJ) OBJ10-J. Do not use public static nonfinal variables