SV.SERIAL.OVERRIDE

Do not invoke overridable methods from the readObject() method

Klocwork reports a SV.SERIAL.OVERRIDE issue for a class when the class directly or indirectly implements the java.io.Serializable interface but the declared method 'readObject' is invoking overridable methods.

Vulnerability and risk

The readObject() method must not call any overridable methods. Invoking overridable methods from the readObject() method can provide the overriding method with access to the object's state before it is fully initialized. This premature access is possible because, in deserialization, the readObject method plays the role of object constructor and therefore object initialization is not complete until readObject exits.

Vulnerable code example 1

Copy
  class SV_SERIAL_OVERRIDE implements Serializable {
     private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
         stream.readObject();
         publicMethod();
         protectedMethod();
     }
     public void publicMethod() {
     }
     protected void protectedMethod() {
    }
  }

In this example, Klocwork reports an SV.SERIAL.OVERRIDE defect at line 4, indicating, "Overridable method 'publicMethod()' invoked from readObject() method" and line 5, indicating "Overridable method 'protectedMethod()' invoked from readObject() method".

Fixed code example 1

Copy
  class SV_SERIAL_OVERRIDE implements Serializable {
     private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
         stream.readObject();
         publicMethod();
         protectedMethod();
     }
     private void publicMethod() {
     }
     private void protectedMethod() {
    }
  }

In this example, Klocwork no longer reports SV.SERIAL.OVERRIDE defects on lines 4 or 5 because publicMethod() and privateMethod() are declared as 'private' and can therefore not be overridden.

Vulnerable code example 2

Copy
  class SV_SERIAL_OVERRIDE implements Serializable {
     private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
         stream.readObject();
         method1();
         method2();
     }
     void method1() {
     }
     void method2() {
    }
  }

In this example, Klocwork reports an SV.SERIAL.OVERRIDE defect on line 4, indicating, "Overridable method 'method1()' invoked from readObject() method" and on line 5, indicating, "Overridable method 'method2()' invoked from readObject() method."

Fixed code example 2

Copy
  class SV_SERIAL_OVERRIDE implements Serializable {
     private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
         stream.readObject();
         method1();
         method2();
     }
     final void method1() {
     }
     final void method2() {
    }
  }

In this example, Klocwork no longer reports SV.SERIAL.OVERRIDE defects on lines 4 or 5 because because method1() and method2() are declared as 'final' and can therefore not be overridden.

Related checkers

Security training

Application security training materials provided by Secure Code Warrior.