When an application saves an in-memory object to bytes and later loads those bytes back into an object, that round-trip is called serialization (saving) and deserialization (loading). It is useful: a session, a message, or a cached record can be stored or sent as a compact blob and reloaded on demand.
The danger arises when two conditions are both true:
- The deserializer is generic — it can reconstruct any type, not just a fixed data class the application chose.
- The bytes come from an attacker — a request body, a cookie, a file upload, or a message queue.
When a generic deserializer loads attacker-supplied bytes, it must instantiate objects to reconstruct them. Instantiating objects runs code: constructors, callbacks, and "rehydration hooks." The attacker controls the bytes, so the attacker controls which types are instantiated — and therefore which code runs, inside the application's own process.
Scope reminder: perform deserialization testing only against systems you own or are explicitly authorized to test.
In this lesson you will:
- Understand why a generic deserializer is dangerous through one concrete example (Python
pickle). - See why "I only read one field from the result" is not a defense.
- Identify a dangerous deserialization primitive.
- Apply the durable fix: replace generic deserializers with JSON and schema validation.
Estimated time: fifteen to twenty minutes.
Prerequisites: xxe-and-deserialization for the "damage happens at parse time, not at read time" mental model. Basic familiarity with at least one programming language.
When you are ready, send the Continue signal.