<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/no-we-can-t-harden-node-js-against-prototype-pollution-agutzkidu" -->

---
title: No, We Can't Harden Node.js Against Prototype Pollution
description: Matteo Collina, Node.js TSC member, argues that hardening Node.js core against prototype pollution gadgets is structurally impossible. Once an attacker can...
canonical: https://daily.dev/posts/no-we-can-t-harden-node-js-against-prototype-pollution-agutzkidu
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: No, We Can't Harden Node.js Against Prototype Pollution | daily.dev
og:description: Matteo Collina, Node.js TSC member, argues that hardening Node.js core against prototype pollution gadgets is structurally impossible. Once an attacker can...
og:url: https://daily.dev/posts/no-we-can-t-harden-node-js-against-prototype-pollution-agutzkidu
og:image: https://api.daily.dev/og/posts/agUtzkIdu.png
og:image:alt: No, We Can't Harden Node.js Against Prototype Pollution
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# No, We Can't Harden Node.js Against Prototype Pollution

**[Adventures in Nodeland](https://daily.dev/sources/nodeland)** · 7 min read · 98 upvotes · 2 comments

## Summary

Matteo Collina, Node.js TSC member, argues that hardening Node.js core against prototype pollution gadgets is structurally impossible. Once an attacker can write to Object.prototype, the game is already over — any gadget found in core or a library is just one of infinitely many exit points. Primordials protect Node's own integrity but don't secure application objects. The real fix is at the input boundary: use secure-json-parse to reject __proto__ and constructor.prototype keys before they enter the process, prefer Maps for untrusted keys, and use null-prototype objects for attacker-controlled data. Node.js does not accept prototype pollution in core as a vulnerability in its bug bounty program for this reason.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://adventures.nodeland.dev/archive/no-we-cant-harden-nodejs-against-prototype>

## Questions this post answers

### Why doesn't Node.js treat prototype pollution in core as a security vulnerability eligible for its bug bounty?

Node.js's security team, per Benjamin Gruenbaum, does not accept prototype pollution in core as a bounty-eligible vulnerability because exploiting it always requires the application to already have a prototype pollution bug elsewhere. Once an attacker can write to Object.prototype, they have already won; any specific gadget (like execSync honoring a polluted NODE_OPTIONS) is just one of infinitely many exits, not the actual flaw.

_Developers weighing which security reports to prioritize can track this kind of Node.js runtime nuance on daily.dev._

### How do I stop prototype pollution from JSON.parse before it reaches my application logic?

Use secure-json-parse with protoAction and constructorAction set to 'error' so parsing throws as soon as a __proto__ or constructor.prototype key appears, before the object is ever created. JSON.parse itself only creates a harmless own property named __proto__; the real damage happens later when a recursive merge or Object.assign promotes that key onto the actual prototype chain, so catching it at the parse boundary prevents that promotion entirely.

_Teams hardening request-body parsing can follow secure-json-parse patterns like this via daily.dev._

### Why can't Node.js core just be rewritten to avoid touching Object.prototype and eliminate prototype pollution gadgets?

Because JavaScript reads through the prototype chain everywhere and dispatches to prototype slots through syntax itself, not just method calls, including destructuring, spread, for...of, await on thenables, and template literals. Fully hardening core would require giving every allocated object a null prototype, avoiding every syntactic construct that touches a prototype slot, and forcing every dependency to do the same, which amounts to a different language rather than a hardening pass.

_Engineers debating language-level security tradeoffs can dig into this reasoning further on daily.dev._

## Community discussion

Top comments from developers on daily.dev.

**@pdfopsdev** · 0 upvotes

> ran into this exact class of bug with qs a while back, query-string parsing has its own **proto** vector totally separate from JSON.parse. secure-json-parse only locks one door, you need the same check wherever untrusted keys turn into object keys - query strings, form bodies, yaml configs, all of it.

## Similar posts on daily.dev

- [Optimizing objects with null prototypes](https://daily.dev/posts/optimizing-objects-with-null-prototypes-ut2gbadbw) · Adventures in Nodeland · 83 upvotes · 4 comments
- [How to Fix Common Web Application Security Vulnerabilities in Node.js](https://daily.dev/posts/how-to-fix-common-web-application-security-vulnerabilities-in-node-js-nhhyrhesv) · freeCodeCamp · 3 upvotes · 0 comments
- [Property-Based Testing Caught a Security Bug I Never Would Have Found](https://daily.dev/posts/property-based-testing-caught-a-security-bug-i-never-would-have-found-498pmhojr) · Kiro · 1 upvotes · 0 comments
- [How to Build Secure-by-Default Node.js APIs](https://daily.dev/posts/how-to-build-secure-by-default-node-js-apis-kgzyotifm) · freeCodeCamp · 10 upvotes · 0 comments
- [Critical flaw in Protobuf library enables JavaScript code execution](https://daily.dev/posts/critical-flaw-in-protobuf-library-enables-javascript-code-execution-1jn7mj8hc) · BleepingComputer · 7 upvotes · 1 comments

---

Tags: [#javascript](https://daily.dev/tags/javascript), [#nodejs](https://daily.dev/tags/nodejs), [#appsec](https://daily.dev/tags/appsec)

[View this post on daily.dev](https://daily.dev/posts/no-we-can-t-harden-node-js-against-prototype-pollution-agutzkidu)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"No, We Can't Harden Node.js Against Prototype Pollution","url":"https://daily.dev/posts/no-we-can-t-harden-node-js-against-prototype-pollution-agutzkidu","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/no-we-can-t-harden-node-js-against-prototype-pollution-agutzkidu"},"datePublished":"2026-07-19T16:24:07.012Z","dateModified":"2026-09-14T08:41:19.207Z","description":"Matteo Collina, Node.js TSC member, argues that hardening Node.js core against prototype pollution gadgets is structurally impossible. Once an attacker can...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/5a083a5fa8ca859e2049b73509ceabb7?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/5a083a5fa8ca859e2049b73509ceabb7?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Adventures in Nodeland","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Adventures in Nodeland","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/4ec40f35e6e440c7ab313b37d0039595","url":"https://daily.dev/sources/nodeland"},"commentCount":2,"discussionUrl":"https://daily.dev/posts/no-we-can-t-harden-node-js-against-prototype-pollution-agutzkidu","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":98},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":2}],"keywords":"javascript,nodejs,appsec","timeRequired":"PT7M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Adventures in Nodeland","item":"https://daily.dev/sources/nodeland"},{"@type":"ListItem","position":3,"name":"No, We Can't Harden Node.js Against Prototype Pollution"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/no-we-can-t-harden-node-js-against-prototype-pollution-agutzkidu","comment":[{"@type":"Comment","text":"ran into this exact class of bug with qs a while back, query-string parsing has its own proto vector totally separate from JSON.parse. secure-json-parse only locks one door, you need the same check wherever untrusted keys turn into object keys - query strings, form bodies, yaml configs, all of it.","datePublished":"2026-07-21T18:02:18.763Z","url":"https://daily.dev/posts/agUtzkIdu#c-3kmj0HbLE","author":{"@type":"Person","name":"PDFops","url":"https://daily.dev/pdfopsdev","image":"https://media.daily.dev/image/upload/s---8isRBKc--/f_auto/v1782922291/avatars/avatar_orjMeK8QKaaVZwGq7ScPz?_a=BAMAMicg0"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/no-we-can-t-harden-node-js-against-prototype-pollution-agutzkidu#faq","mainEntity":[{"@type":"Question","name":"Why doesn't Node.js treat prototype pollution in core as a security vulnerability eligible for its bug bounty?","acceptedAnswer":{"@type":"Answer","text":"Node.js's security team, per Benjamin Gruenbaum, does not accept prototype pollution in core as a bounty-eligible vulnerability because exploiting it always requires the application to already have a prototype pollution bug elsewhere. Once an attacker can write to Object.prototype, they have already won; any specific gadget (like execSync honoring a polluted NODE_OPTIONS) is just one of infinitely many exits, not the actual flaw. Developers weighing which security reports to prioritize can track this kind of Node.js runtime nuance on daily.dev."}},{"@type":"Question","name":"How do I stop prototype pollution from JSON.parse before it reaches my application logic?","acceptedAnswer":{"@type":"Answer","text":"Use secure-json-parse with protoAction and constructorAction set to 'error' so parsing throws as soon as a __proto__ or constructor.prototype key appears, before the object is ever created. JSON.parse itself only creates a harmless own property named __proto__; the real damage happens later when a recursive merge or Object.assign promotes that key onto the actual prototype chain, so catching it at the parse boundary prevents that promotion entirely. Teams hardening request-body parsing can follow secure-json-parse patterns like this via daily.dev."}},{"@type":"Question","name":"Why can't Node.js core just be rewritten to avoid touching Object.prototype and eliminate prototype pollution gadgets?","acceptedAnswer":{"@type":"Answer","text":"Because JavaScript reads through the prototype chain everywhere and dispatches to prototype slots through syntax itself, not just method calls, including destructuring, spread, for...of, await on thenables, and template literals. Fully hardening core would require giving every allocated object a null prototype, avoiding every syntactic construct that touches a prototype slot, and forcing every dependency to do the same, which amounts to a different language rather than a hardening pass. Engineers debating language-level security tradeoffs can dig into this reasoning further on daily.dev."}}]}
```

