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 | ||
---|---|---|
| ||
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
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 | ]]></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> |
...