Working with Serialization

1. Implementing Serializable Interface

AspectDetail
Marker interfaceNo methods to implement
RequiredAll non-transient fields must be Serializable
No-arg ctorRequired only in non-Serializable superclass

2. Using ObjectOutputStream and ObjectInputStream

APIUse
writeObject(o)Serialize
readObject()Deserialize (unchecked cast)
writeUnshared / readUnsharedAvoid back-references
OrderRead in same order as written

3. Understanding serialVersionUID

AspectDetail
Declarationprivate static final long serialVersionUID = 1L;
PurposeVersion compatibility check
Auto-generatedCompiler computes from class shape if absent
RecommendationAlways declare explicitly

4. Customizing Serialization

HookUse
writeObject(ObjectOutputStream)Custom write
readObject(ObjectInputStream)Custom read
readObjectNoData()For class evolution
writeReplace / readResolveSubstitute object

5. Using Externalizable Interface

vs SerializableDetail
MethodswriteExternal / readExternal
ControlFull byte-level control
No-arg ctorRequired (public)
UsePerformance-critical or compact format

6. Handling transient Fields

UseReason
Skip fieldNot serialized
Restore in readObjectRecompute / re-init
Sensitive dataPasswords, sessions, derived caches

7. Understanding Serialization Security Risks

RiskMitigation
Gadget chainsRestrict deserializable classes
DoSHash-collision attacks; use input filters
RCEUntrusted streams executing readObject
Best practiceUse JSON/Protobuf instead for external data

8. Using SerialVersionUID Best Practices

PracticeReason
Always declareAvoid surprise InvalidClassException
Bump on incompatible changeReject old streams
Keep on compatible changeAdd fields with sensible defaults
Use serialver toolCompute current value

9. Implementing Custom Serialization Proxies

Example: Serialization proxy

public final class Period implements Serializable {
    private final Date start, end;
    private Object writeReplace() { return new SerProxy(this); }
    private void readObject(ObjectInputStream s) throws InvalidObjectException {
        throw new InvalidObjectException("Use proxy");
    }
    private static final class SerProxy implements Serializable {
        private final Date start, end;
        SerProxy(Period p) { this.start = p.start; this.end = p.end; }
        private Object readResolve() { return new Period(start, end); }
    }
}
BenefitDetail
Invariant safetyReconstruct via real ctor
Immutability preservedNo reflection bypass

10. Understanding Deserialization Vulnerabilities

VulnerabilityExamples
Apache Commons CollectionsInvokerTransformer chain (CVE-2015-7501)
SpringVarious RCE via deserialization gadgets
JNDI injectionOften combined with deser
MitigationAllow-list classes via ObjectInputFilter

11. Using Serialization Filters (ObjectInputFilter)

APIUse
ObjectInputFilter.allowFilter(p, status)Allow-list
setObjectInputFilter(filter)Per-stream
Globaljdk.serialFilter system property
Patterncom.acme.*;!* (allow + reject all)
FactoryPer-context filter via FilterFactory