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;
|
...
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 | ||
---|---|---|
| ||
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(); } } |
...
Compliant Solution (readObject()
, writeObject()
)
This compliant solution declares the readObject()
and writeObject()
methods private and nonstatic to limit their accessibility.:
Code Block | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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 | highHigh | likelyLikely | lowLow | P27 | L1 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
Coverity | 7.5 | UNSAFE_DESERIALIZATION | Implemented |
Related Guidelines
Bibliography
[Sun 2006] | Serialization Specification |
|
...