serialization: Java serialization companion code (UID drift, JEP 290/415 filters, records, JSON/Protobuf comparison)

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01KqJyCidz3ZgRyHABv2GVJh
This commit is contained in:
Claude
2026-09-30 19:03:40 +00:00
parent b31c6716a3
commit 97e7352f45
31 changed files with 867 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
# serialization
Companion code for the ankurm.com post *"Java Serialization in 2026: Why It's Dangerous and What Replaced It."*
Module `serialization` in `java-core-examples`.
All explanation lives in the post; this module holds the runnable evidence and the captured output.
Nothing here uses a real library gadget chain: the "attacker" classes are local classes that print a line.
## Versions
| Component | Version |
|---|---|
| JDK | 25.0.4.1+1 (Temurin, LTS) |
| Jackson (`tools.jackson.core:jackson-databind`) | 3.2.3 |
| protobuf-java | 4.36.2 |
| JMH | 1.37 |
| JUnit Jupiter | 5.11.0 |
| Hardware | 2 vCPU x86-64 VM (timings are indicative, not a leaderboard) |
## Quickstart
```bash
export JDK25_HOME=/path/to/jdk-25
./scripts/run-all.sh # rebuilds and regenerates everything in output/
```
## What is in here
| File | Shows | Output |
|---|---|---|
| `UidInStreamDemo` | the serialVersionUID is stored in the stream; patching it gives `InvalidClassException` | `01` |
| `src/versions/` | two versions of one class compiled separately by `run-all.sh`, without and with an explicit UID | `02`, `03` |
| `ReadObjectRunsCodeDemo` | `readObject` of the class named in the stream runs before the cast; an allow-list filter stops it | `04` |
| `ResourceLimitsDemo` | forged array length, deep graph, `maxarray` / `maxdepth` / `maxbytes` | `05` |
| `RecordsDemo` | records run the canonical constructor on deserialization; ordinary classes run none | `06` |
| `FilterFactoryDemo` | JEP 415 filter factory with a per-request context, on top of `-Djdk.serialFilter` | `07` |
| `Codecs`, `Order`, `order.proto`, `FormatSizeDemo` | the same object as Java serialization, Jackson 3 JSON and Protobuf wire format (hand-coded, no protoc) | `08` |
| `SerializationBenchmark` | JMH round trip of the three encoders | `09` |
| `SerializationTest` | 11 assertions behind the claims above | `10` |
The JMH run is 2 forks, 5 warmup and 8 measurement iterations of 1 s; re-running moves the numbers
but the Java-serialization-is-slowest ordering held in every run here.