CWE-486, Comparison of Classes by Name, covers code that decides an object's type by comparing class names. In Java more than one class can share a name, because a class is identified by its name together with the class loader that defined it. MITRE lists Java.
How it happens
If trust in an object's methods and data is based on its class name, a malicious party can send an object with the same name as a trusted class and gain the trust given to the known type.
// Vulnerable: any class named "TrustedPlugin" passes
if (obj.getClass().getName().equals("com.example.TrustedPlugin")) {
((TrustedPlugin) obj).run();
}
A second class with that same name, loaded from a different source, satisfies the string check. The object is not the class you meant to trust.
What an attacker gains
MITRE lists execution of unauthorized code or commands, with confidentiality, integrity and availability all at risk. If a product relies only on an object's name to establish identity, it may run the wrong code. The record has no observed CVEs.
How to find it
Static analysis can find some instances. A direct search also works: look for getClass().getName() and getSimpleName() feeding an equality test or a switch on a string.
How to fix it
MITRE's guidance is to use class equivalence to determine type. Instead of comparing the name, use getClass() and the == operator against the class itself.
if (obj.getClass() == TrustedPlugin.class) {
((TrustedPlugin) obj).run();
}
This compares the actual class, loader included. When subclasses are acceptable, instanceof is the usual tool.
Quick check
Why is a name not enough to identify a Java class?
The same name can exist in different class loaders and refer to different classes. Only comparing the class itself accounts for that.