Safeguard
Security Guides•

Is JSON safe from deserialization attacks? Myth versus fact

Plain JSON parsing is far safer than native object formats, but libraries that read type names from the data can reopen the risk. Here is what to check.

Safeguard Security Team
3 min read

Mostly, yes, but not always. OWASP recommends pure data formats like JSON over native serialization, because they cannot carry code. The risk returns when a JSON library lets the data name the class to create. Check whether polymorphic typing, autotype or an @type property is enabled.

Why native formats are the problem

Deserialization rebuilds objects from bytes. Native formats include extra features, such as hooks that run during reconstruction, and attackers can repurpose them. OWASP lists the outcomes as denial of service, access control bypass and remote code execution. Its first piece of advice is to avoid native serialization formats where you can.

Plain JSON maps to simple types: strings, numbers, booleans, arrays and objects. A parser produces data, and your code decides what to do with it.

When JSON stops being plain

Some libraries add a feature that embeds type information in the JSON so objects can be rebuilt as specific classes. If the input chooses the class, the attacker chooses what gets instantiated. OWASP's examples:

  • jackson-databind is safe by default unless polymorphism is used.
  • fastjson2 is safe unless its autotype option is enabled.
  • json-io is unsafe, because its @type property lets any class be deserialized.
  • fastjson before version 1.2.68 is unsafe.

OWASP's .NET advice points the same way: keep Json.NET's TypeNameHandling set to None. If you need polymorphism, use an allowlist binder so the deserializer can only create types you named.

Other formats and languages

  • Python: unpickling can execute arbitrary code, so never unpickle untrusted data. Use yaml.safe_load() for untrusted YAML. Treat jsonpickle.decode() on untrusted input as risky.
  • PHP: audit unserialize() and use json_decode() for data exchange.
  • Java: review uses of ObjectInputStream, readObject, XMLDecoder and XStream.
  • .NET: Microsoft says BinaryFormatter cannot be secured, so avoid it.

A short audit

  1. Search for native serialization calls on any data from outside your trust boundary, including queues, caches, cookies and uploaded files.
  2. Where you use JSON with a mapper, search the configuration for polymorphic typing, autotype or type name options.
  3. If polymorphism is needed, replace open ended typing with an allowlist of classes.
  4. Update the library. Old versions have a history of gadget based bypasses, so version matters.
  5. Bind JSON into small data transfer objects, not domain objects with behaviour.

OWASP also warns that filtering is not a magic fix: filtering does not make arbitrary untrusted deserialization safe, so bound the input size separately.

Finding the libraries in your dependency tree

Your own code may be fine while a transitive dependency enables risky features. A dependency inventory shows which serialization libraries and versions you ship. Safeguard's SBOM and dependency scanning can list these, and the free scan at gold.safeguard.sh/scan is a quick way to see what is in a project.

Click through it at your own pace, or open it full screen.

Quick check

Is JSON.parse in a browser or Node dangerous?

It only builds plain data. The risk is what your code does with the result, for example merging it into objects, which is a separate issue.

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.