You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 32 Next »

Serialization can be used maliciously. Examples include using serialization to maliciously violate the intended invariants of a class. Deserialization is equivalent to object construction; consequently all invariants enforced during object construction must also be enforced during deserialization. The default serialized form lacks any enforcement of class invariants; consequently, it is forbidden to use the default serialized form for any class with implementation-defined invariants.

Noncompliant Code Example

In this noncompliant code example (based on [[Bloch 2005]]), a class with singleton semantics uses the default serialized form, which fails to enforce any implementation-defined invariants. Consequently, the malicious code can create a second instance even though the class should have only a single instance. For purposes of this example, we assume that the class contains only nonsensitive data.

public class SingletonClass extends Exception {
  public static final SingletonClass INSTANCE = new SingletonClass();
  private SingletonClass() {
    // Perform security checks and parameter validation
  }

  protected int printData() {
    int data = 1000;
    return data;
  }
}

class Malicious {
  public static void main(String[] args) {
    SingletonClass sc = (SingletonClass) deepCopy(SingletonClass.INSTANCE);
    System.out.println(sc == SingletonClass.INSTANCE);  // Prints false; indicates new instance
    System.out.println("Balance = " + sc.printData());
  }

  // This method should not be used in production quality code
  static public Object deepCopy(Object obj) {
    try {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
       new ObjectOutputStream(bos).writeObject(obj);
      ByteArrayInputStream bin = new ByteArrayInputStream(bos.toByteArray());
      return new ObjectInputStream(bin).readObject();
    } catch (Exception e) { 
      throw new IllegalArgumentException(e);
    }
  }
}

Compliant Solution

This compliant solution adds a custom readResolve() method that replaces the deserialized instance with a reference to the appropriate singleton from the current execution. More complicated cases may also require custom writeObject() or readObject() methods in addition to (or instead of) the custom readResolve() method. Note that the custom serialization methods must be declared final to prevent a malicious subclass from overriding them.

class SingletonClass extends Exception {
  // ...
  private final Object readResolve() throws NotSerializableException {
    return INSTANCE;
  }
}

Risk Assessment

Serializing objects with implementation defined characteristics can corrupt the state of the object.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

SER08-J

low

probable

high

P2

L3

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this guideline on the CERT website.

Bibliography

[[API 2006]] Class Object, Class Hashtable
[[Bloch 2008]] Item 75: "Consider using a custom serialized form"


SER07-J. Make defensive copies of private mutable components      16. Serialization (SER)      SER09-J. Minimize privileges before deserializing from a privileged context

  • No labels