Thursday, June 16, 2011

Twelve rules for developing more secure Java code-Rule 11


Rule 11: Don't compare classes by name

 Sometimes you want to compare the classes of two objects to see whether they are the same; or you want to see whether an object has a particular class. When you do this, be aware that there can be multiple classes with the same name in a JVM. It is a mistake to compare classes by name since different classes can have the same name. A better method is to compare class objects for equality directly. For example, given two objects, A and B, if you want to see whether they are the same class, use this code:
if(a.getClass() == b.getClass()){
        // objects have the same class
}else{
        // objects have different classes
}
You should also be on the lookout for cases of less direct by-name
comparisons. Suppose, for example, you want to see whether an object
has the class "Foo." Here is the wrong way to do it:

if(obj.getClass().getName().equals("Foo"))   // Wrong!
        // objects class is named Foo
}else{
        // object's class has some other name
}
Here's a better way to do it:
if(obj.getClass() == this.getClassLoader().loadClass("Foo")){
        // object's class is equal to the class that this class calls "Foo"
}else{
        // object's class is not equal to the class that
   // this class calls "Foo"
}

 Do note the legalistic comments in the last example. Whenever you use class names, you open yourself up to mix-and-match attacks, as described in Rule 7. You should also know that the Java language forces you to use class names all the time: in variable declarations, instanceof expressions, and exception-catching blocks. Only the designers of Java can prevent mix-and-match attacks, but you can avoid making the problem worse by avoiding by-name class comparisons.

No comments: