Wiki Markup |
---|
In a Java Virtual Machine (JVM), a class is identified by its fully qualified class name and its class loader. 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 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. Java References#JVMSpec 99]\]. |
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 assume that the two objects are of the same class whilst they're not.
Depending on the function that the insecure code performs, it may be vulnerable to a mix-and-match attack. An attacker may supply a malicious class with the same name as the target class. If access to a critical resource is granted based on comparison of class names alone, the malicious class may end up with more privileges than it requires.
Conversely, the assumption that the same codebase will result in the same class in a JVM is error-prone. While the misleading assumption is commonly observed to be true in desktop applications, typically this is not the case with J2EE servlet containers. The containers may 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 appear to the JVM to be two different classes. Also note that the equals()
method may 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 DefaultAuthenticationHandler
and proceeds depending on the result of the comparison.
Code Block | ||
---|---|---|
| ||
// Determine whether object auth has required/expected class name if (auth.getClass().getName().equals("com.application.auth.DefaultAuthenticationHandler")) { // ... } |
The main issue is that another class may exist with the same name in the 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.
Code Block | ||
---|---|---|
| ||
// Determine whether object h has required/expected class name if (auth.getClass() == this.getClassLoader().loadClass("com.application.auth.DefaultAuthenticationHandler")) { // ... } |
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 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.
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 using their names may give an attacker supplied class undesirable privileges.
Guideline | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
OBJ06-J | medium | unlikely | low | P6 | L2 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Wiki Markup |
---|
\[[JVMSpec 1999|AA. Java References#JVMSpec 99]\] [§2.8.1 Class Names|http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html] \[[Christudas 2005|AA. Java References#Christudas 05]\] \[[Mcgraw 1998|AA. Java References#Mcgraw 98]\] \[[Wheeler 2003|AA. Java References#Wheeler 03]\] [Java|http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/java.html] \[[MITRE 2009|AA. Java References#MITRE 09]\] [CWE ID 486|http://cwe.mitre.org/data/definitions/486.html] "Comparison of Classes by Name" |
OBJ05-J. Limit the extensibility of non-final classes and methods to only trusted subclasses 08. Object Orientation (OBJ) OBJ07-J. Understand how a superclass can affect a subclass