Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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, programs must not use the default serialized form for any class with implementation-defined invariants.

The deserialization process creates a new instance of the class without invoking any of the class's constructors. Consequently, any input validation checks present within the constructors are bypassed. Moreover, transient and static fields may fail to reflect their true values because such fields are bypassed during the serialization procedure and consequently cannot be restored from the object stream. As a result, any class with transient fields, and any class that performs validation checks in its constructors, must also perform similar validation checks when being deserialized.

Validating deserialized objects establishes that the object state is within defined limits and ensures that all transient and static fields have their default secure values. Fields that are declared final and contain a constant value will contain the proper value after deserialization , rather than the default value. For example, the value of the field private transient final n = 42 after deserialization will be 42 , rather than 0. Deserialization produces default values for all other cases.

...

This noncompliant code example uses a custom defined readObject() method , but fails to perform input validation after deserialization. The design of the system requires the maximum value of any lottery ticket to be 20,000; however, an attacker can manipulate the serialized array to generate a different number on deserialization.

...

Code Block
bgColor#ccccff
public class Lottery implements Serializable {	
  private transient int ticket = 1;
  private transient SecureRandom draw = new SecureRandom();

  public Lottery(int ticket) {
    this.ticket = (int) (Math.abs(ticket % 20000) + 1);
  }

  public int getTicket() {
    return this.ticket;	
  }

  public int roll() {
    this.ticket = (int) ((Math.abs(draw.nextInt()) % 20000) + 1);
    return this.ticket;
  }

  public static void main(String[] args) {
    Lottery l = new Lottery(2);
    for(int i = 0; i < 10; i++) {
      l.roll();
      System.out.println(l.getTicket());
    }
  }

  private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject();
    this.draw = new SecureRandom();
    roll();
  }
}

Compliant Solution (Non-

...

Serializable)

This compliant solution simply does not mark the Lottery class serializable.

...

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

...

Related Guidelines

MITRE CWE

CWE ID -502, "Deserialization of Untrusted Data"

Secure Coding Guidelines for the Java Programming Language, Version 3.0

Guideline 5-3 View deserialization the same as object construction

...

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="17a8c5726f4398de-e61c484f-422a463b-b71a829b-9d4f0efea0e74e0c4f4f8f2b"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API 06]]

Class Object, Class Hashtable

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="76af352512f044ad-c9441fd5-428f498e-9f6dbfb0-1770a20e2d5ed9fcdc5dcab1"><ac:plain-text-body><![CDATA[

[[Bloch 2008

AA. Bibliography#Bloch 08]]

Item 75: "Consider using a custom serialized form"

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="e2e517f167b7c548-e6e14069-4a4d4d8f-a847a17e-873ae49fae553b2424274d42"><ac:plain-text-body><![CDATA[

[[Greanier 2000

AA. Bibliography#Greanier 00]]

 

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="8d0b87c4f22a5e2b-699bf34c-499241f7-a75da65d-41273d38e0306cf7de40c44c"><ac:plain-text-body><![CDATA[

[[Harold 1999

AA. Bibliography#Harold 99]]

Chapter 11: Object Serialization, Validation

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="e8adcc961b7c2df0-c745bcc7-4b1a4736-98d186ac-42bc25cd5a4f5d122f2111b6"><ac:plain-text-body><![CDATA[

[[Hawtin 2008

AA. Bibliography#Hawtin 08]]

Antipattern 8: Believing deserialisation is unrelated to construction

]]></ac:plain-text-body></ac:structured-macro>

...