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|AA. Bibliography#JVMSpec 99]\]. A class with the same name but a different package name is different, and a class with the same fully qualified name but which has been loaded by a different class loader is also different.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. Wiki Markup
It could be necessary Sometimes it is desirable to check whether a given object has a specific class type or whether two objects have the same class type associated with them, for example, when implementing the equals()
method. If the comparison is performed incorrectly, the code might could assume that the two objects are of the same class when they are not. As a result, class names must not be compared.
Depending on the function that the insecure code performs, it may could be vulnerable to a mix-and-match attack. An attacker may could supply a malicious class with the same fully qualified name as the target class. If access to a critical protected resource is granted based on the comparison of class names alone, the malicious class may end up with more privileges than is warrantedunprivileged class could gain unwarranted access to the resource.
Conversely, the assumption that two classes deriving from the same codebase are themselves 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 may 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 codebase , may could appear to the JVM to be two different classes. Also note that the equals()
method may might not return true when comparing objects originating from the same codebase.
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 proceeds depending branches on the result of the comparison.:
Code Block | ||
---|---|---|
| ||
// Determine whether object auth has required/expected class nameobject if (auth.getClass().getName().equals( "com.application.auth.DefaultAuthenticationHandler")) { // ... } |
Multiple classes may exist with the same name in the JVM; consequently this is not a valid comparisonComparing 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 object auth
to the class object of the class that the current class loader loads, instead of comparing just the class names.for the canonical default authentication handler:
Code Block | ||
---|---|---|
| ||
// Determine whether object hauth has required/expected class name if (auth.getClass() == this.getClassLoader().loadClass("com.application.auth.DefaultAuthenticationHandler".class)) { // ... } |
The call to loadClass()
returns the class having the specified name in the current namespace (consisting of the class name and the defining classloader), and 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.
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 objectsObjects 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 objectsObjects have the same class } |
Risk Assessment
Comparing classes solely using their names may can allow a malicious class to gain elevated privilegesbypass security checks and gain access to protected resources.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|
OBJ09-J |
High |
Unlikely |
Low | P9 | L2 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this guideline on the CERT website.
Bibliography
Wiki Markup |
---|
\[[Christudas 2005|AA. Bibliography#Christudas 05]\]
\[[JVMSpec 1999|AA. Bibliography#JVMSpec 99]\] [§2.8.1 Class Names|http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html]
\[[Mcgraw 1998|AA. Bibliography#Mcgraw 98]\]
\[[MITRE 2009|AA. Bibliography#MITRE 09]\] [CWE ID 486|http://cwe.mitre.org/data/definitions/486.html] "Comparison of Classes by Name"
\[[Wheeler 2003|AA. Bibliography#Wheeler 03]\] [Java|http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/java.html] |
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" | |
...
OBJ05-J. Limit extensibility of classes and methods with invariants to trusted subclasses only 04. Object Orientation (OBJ) OBJ07-J. Understand how a superclass can affect a subclass