mediumCVSS 6.2Vulnerability

CVE-2026-71429

## Description The path filters `pick`, `ignore`, `filter`, and `replace` — the library's headline "surgical extraction" feature — recompute the full path string from the nesting stack on **every checkable token**. Because the stack length equals the current nesting depth, and a checkable token is emitted at every level, processing a document of depth *D* costs **O(D²)**, not O(D). This is triggered by document **structure (nesting depth), not byte volume**, so a tiny payload achieves outsized CPU cost, and it is the ordinary "traverse until the filter matches" path — including the exact README flagship example `pick({filter: 'data'})`. Any service that uses these filters to extract a field from an untrusted (or larger-than-memory) JSON body — the primary documented use case — can be made to block its event loop. ### Affected code (v3.4.0) `src/core/filters/filter-base.js`: ```js // L26-32 — string filter: rejoins the ENTIRE stack on every call const stringFilter = (string, separator) => { const stringWithSeparator = string + separator; return stack => { const path = stack.join(separator); // O(depth) — every call return path === string || path.startsWith(stringWithSeparator); }; }; // L34-39 — regexp filter: same const regExpFilter = (regExp, separator) => { return stack => { regExp.lastIndex = 0; return regExp.test(stack.join(separator)); // O(depth) — every call }; }; ``` ```js // L194 — filter(stack, chunk) is invoked for EVERY checkable token while in the 'check' state const action = checkableTokens[chunk.name] !== 1 ? nonCheckableAction : filter(stack, chunk) ? specialAction : defaultAction; ``` `stack` is pushed/popped on `startObject`/`startArray`/end (L239-250), so `stack.length === depth`. For a depth-*D* document that hasn't matched yet, `filter()` runs once per level and each call is O(depth) ⇒ **O(D²)** total. **Not affected:** the `streamArray`/`streamObject`/`streamValues` streamers use `asm.depth`

Properties

ghsa_id
GHSA-528h-pc64-c93x
severity
medium
summary
stream-json: pick/ignore/filter/replace filters are O(depth²) on nested input — small crafted JSON blocks the event loop for seconds→minutes (DoS)
cvss_score
6.2
cve_id
CVE-2026-71429
cvss_vector
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
is_ghsa_only
false
ghsa_published
2026-09-03T20:27:53Z
source_url
https://github.com/advisories/GHSA-528h-pc64-c93x
ghsa_updated
2026-09-03T20:27:54Z

Related Entities (4)

VULNERABLE_TO (1)

[Software]npm/stream-json

AFFECTS (1)

[Software]npm/stream-json

HAS_WEAKNESS (1)

[Weakness]Inefficient Algorithmic Complexity

REPORTED_BY (1)

[Source]GitHub Advisory Database

Explore deeper with Ninja Signal's threat intelligence graph

CVE-2026-71429 (CVSS 6.2) — Ninja Signal Threat Intelligence | Ninja Signal