Serializable class can overload the
readObject() method, which is called when an object of that class is being deserialized. Both this method and the
readResolve() method should refrain from performing potentially dangerous operations.
A class that performs dangerous operations in the constructor must not be
Serializable. This is because SER07-J. Do not use the default serialized form for classes with implementation-defined invariants would require that its
readObject() method perform the same dangerous operation as the constructor. As an alternative, such a class could be
readObject() always throws an exception.
This guideline is related to rule SER12-J. Prevent deserialization of untrusted data.
Non-Compliant Code Example
In the following non-compliant code example, the class
OpenedFile opens a file during deserialization. Operating systems typically impose a limit on the number of open file handles per process. Usually, this limit is not large (e.g., 1024). Consequently, deserializing a list of
OpenedFile objects can consume all file handles available to the process and consequently cause the program to malfunction if it attempts to open another file before the deserialized
OpenedFile objects get garbage-collected.
In this compliant solution, potentially dangerous operations are moved outside of deserialization, and users of the class are required to make a separate call to
init() after deserializing.
In this compliant solution, we assume that
OpenedFile must be
Serializable because it inherits from a serializable superclass. Because
OpenedFile must perform dangerous operations in the constructor, it intentionally forbids deserialization by throwing an exception in
CERT Vulnerability #576313 describes a family of exploitable vulnerabilities that arise from violating this rule.
The severity of violations of this rule depend on the nature of the potentially dangerous operations performed. If only mildly dangerous operations are performed, the risk might be limited to denial-of-service (DoS) attacks. At the other extreme, remote code execution is possible if attacker-supplied input is supplied to methods such as
Runtime.exec (either directly or via reflection).
|Useful for developing exploits that detect violation of this rule|