Every serializable container class that has private mutable sub-objects instance variables must defensively copy these sub-objects them in the readObject()
method. An adversary can append attacker can tamper with the serialized form of such a class, appending extra references to the sub-objects to generate a new byte stream. When deserialized, this byte stream will could allow the creation of a container class instance whose internal sub-object references will be attacker controllable. This would in turn allow the instance of the container class to mutate and violate its guaranteesvariable references are controlled by the attacker. Consequently, the class instance can mutate and violate its class invariants.
This rule is an instance of OBJ06-J. Defensively copy mutable inputs and mutable internal components, which applies to constructors and to other methods that accept untrusted mutable arguments. This rule applies the same principle to deserialized mutable fields.
Noncompliant Code Example
There is no defensive copying of the mutable components or sub-objects (Date
object) in this noncompliant code example. An attacker may This noncompliant code example fails to defensively copy the mutable Date
object date
. An attacker might be able to create an instance of MutableSer
with a mutated value of the date
sub-object whose date
object contains a nefarious subclass of Date
and whose methods can perform actions specified by an attacker. Any code that depends on the immutability of the subobject is vulnerable.
Code Block | ||
---|---|---|
| ||
class MutableSer implements Serializable { private static final Date epoch = new Date(0); private Date date = null; // mutableMutable component public MutableSer(Date d){ date = new Date(d.getTime()); // constructorConstructor performs defensive copying } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); //perform Perform validation if necessary } } |
Compliant Solution
This compliant solution creates a defensive copy of the mutable Date
object date
in the readObject()
method. Note the use of field-by-field input and validation of incoming fields. Additionally, note that this compliant solution is insufficient to protect sensitive data (see SER03-J. Do not serialize unencrypted sensitive data for additional information).
Code Block | ||
---|---|---|
| ||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ObjectInputStream.GetField fields = ois.defaultReadObject(readFields(); Date inDate = (Date) fields.get("date", epoch); //defensively Defensively copy the mutable component date = new Date(dateinDate.getTime()); //perform Perform validation if necessary } |
Note that there is no need to copy immutable sub-objects. Also, avoid using the sub-object's {{clone()}} method since it can be overridden when the sub-object's class is non-final. The sub-objects ({{date}}) themselves must be non-final so that defensive copying can occur. It is also inadvisable to use the {{writeUnshared}} and {{readUnshared}} methods as an alternative \[[Bloch 08|AA. Java References#Bloch 08]\There is no need to copy immutable subobjects. Also, avoid using the subobject's Wiki Markup clone()
method because it can be overridden when the subobject's class is not final and produces only a shallow copy. The references to the subobjects themselves must be nonfinal so that defensive copying can occur. It is also inadvisable to use the writeUnshared()
and readUnshared()
methods as an alternative [Bloch 2008].
Risk Assessment
Failure to defensively copy mutable components during deserialization can violate the immutability contract of an object.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|
SER06-J |
Low |
Probable |
Medium | P4 | L3 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Wiki Markup |
---|
\[[API 06|AA. Java References#API 06]\]
\[[Sun 06|AA. Java References#Sun 06]\] "Serialization specification: A.6 Guarding Unshared Deserialized Objects"
\[[Bloch 08|AA. Java References#Bloch 08]\] Item 76: "Write readObject methods defensively" |
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
CodeSonar |
| JAVA.CLASS.SER.ND | Serialization Not Disabled (Java) | ||||||
Coverity | 7.5 | UNSAFE_DESERIALIZATION | Implemented |
Related Guidelines
Bibliography
[API 2014] | |
Item 76, "Write | |
[Sun 2006] | Serialization Specification, A.6, Guarding Unshared Deserialized Objects |
...
SER33-J. Do not serialize instances of inner classes 11. Serialization (SER) 11. Serialization (SER)