Object serialization allows an object's state to be saved as a sequence of bytes and then reconstituted at a later time. The primary application of serialization is in Java Remote Method Invocation (RMI) wherein objects must be packed (marshalled), exchanged between distributed virtual machines and subsequently unpacked (unmarshalled). It also finds extensive use in Java Beans.Java language's access control mechanisms are ineffective after a class is serialized. Consequently, any sensitive data that was originally protected using Default serialization lacks protection for data that has been serialized. An attacker who gains access to the serialized data can use it to discover sensitive data, to determine implementation details of the objects, and for many other purposes. Similarly, an attacker can modify the serialized data in an attempt to compromise the system when the malicious data is deserialized. Consequently, sensitive data that is serialized is potentially exposed, without regard to the access qualifiers (such as the private
keyword) are exposedthat were used in the original code. Moreover, the security manager does not provide any checks to lacks checks that could guarantee integrity of the serialized data.
Examples of sensitive data that should not be serialized are remain unserialized include cryptographic keys, digital certificates, and classes that may hold references to sensitive data at the time of serialization.
...
The data members of class Point
are declared as private
. The saveState()
and readState()
methods are used for serialization and de-serialization respectively. The If the coordinates (x,y)
that are written to were sensitive (as we assume for this example), their presence in the data stream are susceptible exposes them to malicious tampering.
Code Block | ||
---|---|---|
| ||
public class Point { private double x; private double y; public Point(double x, double y) { this.x = x; this.y = y; } public Point() { // No argument constructor } } public class Coordinates extends Point implements Serializable { public static void main(String[] args) { try { Point p = new Point(5, 2); FileOutputStream fout = new FileOutputStream("point.ser"); ObjectOutputStream oout = new ObjectOutputStream(fout); oout.writeObject(p); oout.close(); } catch (Throwable t) { // Forward to handler } } } |
...
In the absence of sensitive data, a class classes can be serialized by simply implementing the java.io.Serializable
interface (sensitive classes should not implement this interface). By doing so, the class indicates that no security issues may result from the object's serialization. Note that any derived sub classes also inherit this interface and are consequently serializable. This simple approach is inappropriate for any class that contains sensitive data.
When serialization is unavoidable, it is possible that the class suffers from serializability issues. Usually, this happens when there are references to non-serializable objects within the serializable class. This compliant solution avoids the possibility of incorrect serialization and also protects sensitive data members from being serialized accidentally. The basic idea is to declare the target member as transient
so that it is not included in the list of fields to be serialized, whenever default serialization is used.
...