Safeguard
Security Guides•

Java deserialization: allowlist filters and what they cannot fix

Reduce Java native deserialization risk with serialization filters and class allowlists, which libraries are safe by default, and why filters are no cure.

Safeguard Security Team
4 min read

Best option: do not deserialize untrusted Java objects at all. If you cannot avoid it, configure a serialization filter with an application specific class allowlist and resource limits before reading any object. OWASP is blunt that filtering does not make arbitrary untrusted deserialization safe.

Why Java deserialization is dangerous

When Java reads a serialized stream, it creates objects and runs their special methods such as readObject. If an attacker can choose which classes appear in the stream, they can chain together existing classes on your classpath to do things you never intended. New chains keep being found, so lists of known bad classes are always incomplete.

OWASP lists signs that Java serialization is in use: the bytes AC ED 00 05, the Base64 prefix rO0, and the content type application/x-java-serialized-object. Spotting those in traffic or storage tells you where to look.

Step 1: remove the need

OWASP's general advice is to prefer pure data formats such as JSON or XML with data transfer objects. A deserializer can only instantiate types that it knows about, so make the type fixed by your code, not chosen by the data.

Step 2: filter when you cannot

OWASP says to configure serialization filters with an allowlist of expected classes and limits on graph depth, number of references, array length and stream size. Limits matter because class checks alone do not bound resource use.

Two details from the cheat sheet:

  • Filters are not called for concretely encoded strings or primitives, so cap the input size separately.
  • Overriding resolveClass() to permit one expected class is an illustration, not a full defense. It does not check every object, and dynamic proxy descriptors go through resolveProxyClass().

An allowlist is stronger than a blocklist because you list what the application needs, not what attackers have already used.

Step 3: harden the domain objects

  • Make a final readObject() that always throws on classes that must not be deserialized.
  • Mark sensitive fields private transient so they are not serialized or controllable through deserialization.
  • Review sinks: readObject, readResolve, readExternal, readUnshared, XMLDecoder and XStream.fromXML.

Libraries that matter

OWASP's notes on other Java libraries are worth checking against your dependency list. Per its page, these are safe with default configuration: fastjson2, Jackson without polymorphism, Kryo 5.0.0 and later, YamlBeans 1.16 and later, and XStream 1.4.17 and later. Others need configuration, such as SnakeYAML with SafeConstructor, or should not be used with untrusted input, such as the JDK XMLDecoder. Check the current page for the full list, since it changes.

When you do not own the code

If a third party library deserializes and you cannot patch it quickly, OWASP mentions agents that instrument all ObjectInputStream use. It warns a global change is only safe for blocking known malicious types.

A short plan

  1. Inventory where ObjectInputStream and similar sinks appear.
  2. Replace the ones on public paths with JSON and explicit types.
  3. Put filters in front of the rest.
  4. Keep libraries current and scan for known gadget bearing versions.

Safeguard's SBOM and dependency scanning and reachability analysis help with step 4. A free scan is at gold.safeguard.sh/scan. For other languages see serialization risk across Python, Java and .NET.

Quick check

Is a class allowlist enough?

It is the right first control, but OWASP says filtering does not make untrusted deserialization safe. Add size limits and avoid native serialization where possible.

How do I tell if my service uses Java serialization?

Search for ObjectInputStream, and look for the byte prefix AC ED 00 05 or Base64 rO0 in traffic and stored data.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.