logo

Database

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