Lion Cipher Lab
Build a Java deserialization gadget chain to RCE — then shut it with an ObjectInputFilter allowlist
- AppSec / DevSecOps
- Advanced
- ~75 min
- Free · no account required
Why it matters
Java's built-in serialization — ObjectOutputStream to turn an object into bytes, ObjectInputStream.readObject() to turn bytes back into an object — is one of the most quietly dangerous features in enterprise software. The trap is the same one the Python pickle lab shows, but bigger: readObject() does not just copy fields, it RUNS code as it rebuilds an object graph (each class's own readObject, plus side effects in methods that get invoked during reconstruction). By itself that is harmless. The danger is a GADGET CHAIN: an attacker strings together classes that are ALREADY on the…
What you'll learn
- Java native serialization internals (readObject / ObjectInputStream)
- gadget chains and how ysoserial builds them
- reaching remote code execution from an untrusted-bytes sink
- JEP 290 serialization filtering (ObjectInputFilter allowlists)
- why a data-only format is the durable fix
Steps in this lab
- The vocabulary: serialization, readObject, and what a 'gadget chain' really is
- Set up a throwaway Java lab in Docker (install nothing but Docker)
- Build the VULNERABLE service (it deserializes untrusted bytes)
- Get ysoserial — the gadget-chain generator
- Fire the chain — prove remote code execution
- Why this works, and where it hides in real systems
- Defense 1 — an ObjectInputFilter allowlist (JEP 290), the JDK's own brake
- Defense 2 — the durable fix: don't deserialize untrusted native Java at all
- What you did — and the judgment to carry
- Clean up