Safeguard
Security Guides•

Does Fastify block __proto__ in JSON request bodies by default?

Fastify rejects JSON bodies with __proto__ or constructor keys by default via secure-json-parse. See the options, tradeoffs and what it misses.

Safeguard Security Team
3 min read

Yes. Fastify's onProtoPoisoning and onConstructorPoisoning options both default to error, so a JSON body containing a __proto__ or constructor key is rejected. The behavior comes from the secure-json-parse library. It guards the parsing step only, not what your own code does with the data afterward.

Definition

Prototype poisoning, also called prototype pollution, is an attack where input sets properties on a shared object prototype, so unrelated objects inherit attacker chosen values. JSON is a common carrier because a body can include a key literally named __proto__.

The Fastify guide on the topic reproduces an article by Eran Hammer. Its explanation is that JSON.parse creates a plain property with the name __proto__, which by itself is harmless. The danger appears when other code, such as Object.assign, copies that property into another object, where the magic name becomes an actual prototype.

The two options

OptionDefaultPossible values
onProtoPoisoningerrorerror, remove, ignore
onConstructorPoisoningerrorerror, remove, ignore

Per the Fastify server reference, these define the action the framework takes when parsing a JSON object with __proto__ or with constructor, and the functionality is provided by secure-json-parse.

Which value to use

ValueResultWhen it fits
errorRequest failsMost APIs. Legitimate clients never send these keys
removeKey dropped, request continuesTolerant gateways where you cannot fix clients
ignoreNothing doneAlmost never. Only if you handle it elsewhere

Leave the default unless you have a concrete reason. If you must change it, write down why in the code.

Steps to check your own service

  1. Search your server creation code for onProtoPoisoning and onConstructorPoisoning. If neither is present you are on the defaults.
  2. Send a JSON body with a __proto__ key to a test route and confirm you get an error.
  3. Check custom content type parsers. A parser you write yourself replaces the default JSON handling, so the protection may not apply. Use secure-json-parse inside it.
  4. Review code that merges request data into other objects with deep merge helpers.
  5. Add the test to CI so a refactor cannot remove the protection quietly.

What this does not cover

The option only sees JSON bodies. Query strings, form bodies and data from other services follow other paths. And any code that recursively merges untrusted objects can still be tricked, even if the framework blocked the obvious key. The Fastify guide itself notes that any solution that uses JSON.parse to process external data is potentially at risk.

For defenses inside your own code, see prototype pollution defenses and how to prevent prototype pollution in JavaScript. Schema validation helps too, see Fastify's Ajv defaults.

Safeguard's dependency scanning and reachability analysis can show whether a vulnerable merge helper in your tree is actually called. Free scan: gold.safeguard.sh/scan.

Quick check

Is my Express app protected the same way?

Not by this Fastify option. Check the JSON parser you use and how your code merges input into objects.

Should I set onProtoPoisoning to remove?

Only if you cannot fix clients that send the key. Rejecting is the safer default for most APIs.

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.