Prototype Pollution In stream-json
Description
stream-json has a prototype pollution issue: Assembler writes this.current[this.key] on plain objects
Summary
A prototype-pollution vulnerability in stream-json lets attacker-controlled JSON replace a parsed object's prototype.
Details
The streaming JSON parser (StreamValues/StreamObject/jsonc variants) writes keys via plain assignment, so a proto key replaces the parsed object's prototype with attacker-controlled content (verified 3.5.0 npm latest; native JSON.parse twin control stays clean). Parsing untrusted JSON is the contract. Assembler in Assembler.js.
PoC
Run:
node poc-stream-json-proto-injection.mjs
Full proof-of-concept source (poc-stream-json-proto-injection.mjs):
// stream-json v3.5.0 (npm latest) — local [[Prototype]] replacement via `__proto__` keys // Class: prototype injection in a JSON deserializer (jsonparse/bser/jsonc-parser/plist family) // Root cause: Assembler builds every object as a plain `Object` and writes // `this.current[this.key] = value` (src/core/assembler.js:160,180 — plain assignment, // ToPropertyKey → inherited Object.prototype __proto__ setter fires) // Spec baseline: JSON.parse (CreateDataProperty) → own data property, no prototype change // Run: node poc-stream-json-proto-injection.mjs (from C:/Users/rncb0/AppData/Local/Temp/0day/sj-lab) import { parser } from 'stream-json';...
Observed output (verbatim, Node 24.15.0, Windows):
RESULT: 21 PASS / 0 FAIL
Impact
Prototype pollution (CWE-1321). Applications parsing attacker-influenced streaming JSON can have authorization checks read attacker-controlled values. Affects stream-json <= 3.5.0; no patched version exists.
Maintainer note on scope
The attack vector is local — stream-json's documented input is data the user owns (database dumps, exports, logs); it is not designed for JSON from the open internet, and the docs now say so. The parsed object's prototype was replaced (never the global Object.prototype); "__proto__": null additionally strips Object.prototype from the parsed object, so ordinary consumer code calling hasOwnProperty() throws. Assembler and FlexAssembler now create an own data property for a __proto__ key, exactly as JSON.parse does.
Mitigation
Update Impact
Minimal update. May introduce new vulnerabilities or breaking changes.
Ecosystem | Component | Affected version | Patched versions |
|---|---|---|---|
npm | 3.6.0 |
Aliases
References