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

Compare with Current View Page History

Version 1 Next »

Object serialization allows saving an object's state as a sequence of bytes and its reconstitution at a later time. The primary application of serialization is in Java Remote Method Invocation (RMI) wherein objects must be (un)packed and exchanged between distributed virtual machines. It also finds extensive use in Java Beans.

After a serializable class is exported, attempts to refactor its code can easily run into the sand. Specifically, the old serialized form (encoded representation) has to be continually supported as it is part of the published API. This can be very troublesome from the security perspective, as it not only promotes dead code but also burdens the provider who has to eternally maintain the existing codebase.

When a class implements Serializable and does not override its functionality, it is said to be using the default serialized form. If the class changes in the future, any byte stream produced by users of the old class will not be compatible with the new implementation. Moving to a custom serialized form releases the implementer from the trap of having to maintain the original serialized form as well as the corresponding version of the class.

Noncompliant Code Example

This noncompliant snippet implements a GameWeapon class with a serializable field called noofWeapons, and uses the default serialization form. Any changes to the internal representation of the class can break the existing serialized form.

class GameWeapon implements Serializable {
  int noofWeapons = 10;
	    
  public String toString() {
    return String.valueOf(noofWeapons);
  }
}

Compliant Solution

Ideally, implement Serializable only when the class is not expected to evolve frequently. One way to maintain the original serialized form, at the same time allowing the class to evolve is to use custom serialization with the help of serialPersistentFields. The static and transient fields allow you to specify what should not be serialized whereas the serialPersistentFields field specifies what should be serialized. It also relieves the class from defining the serializable field within the class implementation, thus decoupling the current implementation from the logic. New fields can easily be added without breaking compatibility across releases.

class WeaponStore implements Serializable {
  int noofWeapons = 10; // total number of weapons	
}

public class GameWeapon implements Serializable {
  WeaponStore ws = new WeaponStore();
  private static final ObjectStreamField[] serialPersistentFields
    = {new ObjectStreamField("ws", WeaponStore.class)};

  private void readObject(ObjectInputStream ois) throws IOException {
    try {
      ObjectInputStream.GetField gf = ois.readFields();
      this.ws = (WeaponStore) gf.get("ws", ws);
    } catch (ClassNotFoundException e) { /* call handler */ }
  }
	 
  private void writeObject(ObjectOutputStream oos) throws IOException {
    ObjectOutputStream.PutField pf = oos.putFields();
    pf.put("ws", ws);
    oos.writeFields();
  }
	 
  public String toString() {
    return String.valueOf(ws);
  }
}

Notably, according to [[Sun 06]]:

Inner classes can only contain final static fields that are initialized to constants or expressions built up from constants. Consequently, it is not possible to set serialPersistentFields for an inner class (though it is possible to set it for static member classes).

Risk Assessment

Failure to provide a consistent serialization mechanism across releases can limit the extensibility of classes. If classes are extended, a can of compatibility vulnerabilities may get introduced.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

SER00-J

low

probable

high

P2

L3

Automated Detection

TODO

Related Vulnerabilities

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

References

[[Sun 06]] "Serialization specification", "1.5 Defining Serializable Fields for a Class" and "1.7 Accessing Serializable Fields of a Class"
[[API 06]]


11. Serialization (SER)      11. Serialization (SER)      11. Serialization (SER)

  • No labels