Versions Compared

Key

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

Classes that require special handling during object serialization and deserialization must implement special methods with exactly the following signatures [API 20062014]:

Code Block

private void writeObject(java.io.ObjectOutputStream out) 
    throws IOException;
private void readObject(java.io.ObjectInputStream in)
    throws IOException, ClassNotFoundException;
private void readObjectNoData()
    throws ObjectStreamException;

Wiki MarkupNote that these methods must be declared private for any serializable class. Serializable classes may also implement the {{readResolve()}} and {{writeReplace()}} methods.
According to the Serialization Specification \ [[Sun 2006|AA. References#Sun 06]\], {{readResolve()}} and {{writeReplace()}} method documentation:

For Serializable and Externalizable classes, the readResolve method allows a class to replace/resolve the object read from the stream before it is returned to the caller. By implementing the readResolve method, a class can directly control the types and instances of its own instances being deserialized.

For Serializable and Externalizable classes, the writeReplace method allows a class of an object to nominate its own replacement in the stream before the object is written. By implementing the writeReplace method, a class can directly control the types and instances of its own instances being serialized.

...

Noncompliant Code Example (readObject(), writeObject())

This noncompliant code example shows a class Ser with a private constructor, indicating that code external to the class should be unable to create instances of it. The class implements java.io.Serializable and defines public readObject() and writeObject() methods. Consequently, untrusted code can obtain the reconstituted objects by using readObject() and can write to the stream by using writeObject().

Code Block
bgColor#FFcccc

public class Ser implements Serializable {
  private final long serialVersionUID = 123456789;
  private Ser() {
    // initializeInitialize
  }
  public static void writeObject(final ObjectOutputStream stream)
    throws IOException {
    stream.defaultWriteObject();
  }	
  public static void readObject(final ObjectInputStream stream)
      throws IOException, ClassNotFoundException {
    stream.defaultReadObject();
  }
}

Similarly, omitting the static keyword is insufficient to make this example secure; Note that there are two things wrong with the signatures of writeObject() and readObject() in this Noncompliant Code Example: (1) the method is declared public instead of private, and (2) the method is declared static instead of non-static.  Since the method signatures do not exactly match the required signatures, the JVM will not detect the two methods, resulting in failure to use the custom serialized form.

Compliant Solution (readObject(), writeObject())

This compliant solution declares the readObject() and writeObject() methods private and nonstatic to limit their accessibility. :

Code Block
bgColor#ccccff

private void writeObject(final ObjectOutputStream stream)
    throws IOException {
  stream.defaultWriteObject();
}

private void readObject(final ObjectInputStream stream)
    throws IOException, ClassNotFoundException {
  stream.defaultReadObject();
}

...

Noncompliant Code Example (readResolve(), writeReplace())

This noncompliant code example declares the readResolve() and writeReplace() methods as private.:

Code Block
bgColor#FFCCCC

class Extendable implements Serializable {
  private Object readResolve() {
    // ...
  }

  private Object writeReplace() {
    // ...
  }
}

Noncompliant Code Example (readResolve(), writeReplace())

This noncompliant code example declares the readResolve() and writeReplace() methods as static.:

Code Block
bgColor#FFCCCC

class Extendable implements Serializable {
  protected static Object readResolve() {
    // ...
  }

  protected static Object writeReplace() {
    // ...
  }
}

Compliant Solution (readResolve(), writeReplace())

This compliant solution declares the two methods protected while eliminating the static keyword so that subclasses can inherit them.:

Code Block
bgColor#ccccff

class Extendable implements Serializable {
  protected Object readResolve() {
    // ...
  }

  protected Object writeReplace() {
    // ...
  }
}

...

Deviating from the proper signatures of serialization methods can lead to unexpected behavior. Failure to limit the accessibility of the readObject() and writeObject() methods can leave code vulnerable to untrusted invocations. Declaring readResolve() and writeReplace() methods to be static or private can force subclasses to silently ignore them, while declaring them public allows them to be invoked by untrusted code.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

SER01-J

high

High

likely

Likely

low

Low

P27

L1

Automated Detection

Tool
Version
Checker
Description
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

JAVA.CLASS.SER.ND

Serialization Not Disabled (Java)

Coverity7.5UNSAFE_DESERIALIZATIONImplemented
Parasoft Jtest
Include Page
Parasoft_V
Parasoft_V
CERT.SER01.ROWOEnsure that the 'readObject()' and 'writeObject()' methods have the correct signature
PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V6075
SonarQube
Include Page
SonarQube_V
SonarQube_V
S2061Custom serialization method signatures should meet requirements

Related Guidelines

MITRE CWE

CWE-502

.

, Deserialization of

untrusted data

Untrusted Data

Bibliography

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="a3218d22-43b5-4cc4-9d87-8a56acd95c27"><ac:plain-text-body><![CDATA

[

[[API 2006

AA. References#API 06]]

Serializable

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="1e86e842-61d6-47dc-a611-5791499c08ac"><ac:plain-text-body><![CDATA[

[[Sun 2006

AA. References#Sun 06]]

Serialization Specification

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="04039039-5477-4653-95be-692696ce6f53"><ac:plain-text-body><![CDATA[

[[Ware 2008

AA. References#Ware 08]]

 

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

API 2014]

Class Serializable

[Sun 2006]

Serialization Specification

[Ware 2008]



...

Image Added Image Added Image AddedSER00-J. Maintain serialization compatibility during class evolution      13. Serialization (SER)      SER02-J. Sign then seal sensitive objects before sending them outside a trust boundary