Recipe Name:
Do not compare classes/types by their name (literal)
Description:
Comparing the class names is less robust than comparing the actual classes
Level:
warning
Language:
  • java
Tags:
  • Java basic
  • SEI CERT
  • quality
  • security
Documentation

Comparing classes/types based on the class name is less robust than comparing the class itself.

By using the classes of the types themselves, there is less room for error as type checking can be performed. This implicitly checks the packages of the classes as well, which might be forgotten when providing the class name as a string literal. This in turn could lead to a mix-and-match attack in which the attacker creates a class with the same name in a different package.

Before
b.add(obj1.getClass().getName().equals("java.lang.Integer"));
b.add("java.lang.Integer".equals(obj1.getClass().getName()));
b.add(obj1.getClass().getName().equals(obj2.getClass().getName()));
After
b.add(obj1.getClass() == Integer.class);
b.add(obj1.getClass() == Integer.class);
b.add(obj1.getClass() == obj2.getClass());
References
Recipe
id: scw:java:basic:class-compare-literal
version: 10
metadata:
  name: Do not compare classes/types by their name (literal)
  shortDescription: Comparing the class names is less robust than comparing the actual classes
  level: warning
  language: java
  scwCategory: blog:generic
  cweCategory: 480
  enabled: true
  descriptionFile: descriptions/Do_not_compare_classes_types_by_their_name.html
  tags: Java basic;SEI CERT;quality;security
search:
  methodcall:
    args:
      1:
        value:
          is:
            literal: {}
    name: equals
    "on":
      methodcall:
        name: getName
        "on":
          methodcall:
            name: getClass
availableFixes:
- name: Compare classes instead of names
  actions:
  - rewrite:
      to: '{{{ qualifier.qualifier }}} == {{#sed}}s/.*\.(.*)/$1/,{{{ argumentList.expressions }}}{{/sed}}.class'