CVE-2026-8657 Overview
CVE-2026-8657 is a prototype pollution vulnerability [CWE-1321] in the jsondiffpatch npm package, affecting all versions before 0.7.6. The flaw exists in the jsondiffpatch.patch() and jsondiffpatch/formatters/jsonpatch.patch() APIs. Attackers can supply crafted delta or JSON Patch documents containing special property names such as __proto__, constructor, or prototype. The library traverses these attacker-controlled path segments without filtering, allowing modification of Object.prototype. This pollution propagates across every object in the running Node.js process, enabling downstream attacks such as denial of service, logic bypass, and in some cases remote code execution depending on the host application.
Critical Impact
Successful exploitation allows attackers to modify Object.prototype globally, corrupting application state and enabling secondary attacks against any code that reads from JavaScript objects.
Affected Products
- jsondiffpatch npm package versions before 0.7.6
- Applications calling jsondiffpatch.patch() with untrusted delta input
- Applications calling jsondiffpatch/formatters/jsonpatch.patch() with untrusted RFC 6902 JSON Patch input
Discovery Timeline
- 2026-05-16 - CVE-2026-8657 published to NVD
- 2026-05-19 - Last updated in NVD database
Technical Details for CVE-2026-8657
Vulnerability Analysis
The jsondiffpatch library applies structured delta documents to JavaScript objects to reproduce changes between two states. The patch() function walks the delta tree and assigns values to keys on the target object using attacker-controlled property names. The JSON Patch formatter parses RFC 6902 path strings and traverses nested objects using each path segment as an index.
Neither code path validated property names against JavaScript's reserved prototype-related keys. When a delta or JSON Patch document specified __proto__, constructor, or prototype as a key, the library wrote through to Object.prototype rather than the intended target object. Because every JavaScript object inherits from Object.prototype, any modification immediately affected every other object in the process.
Root Cause
The root cause is missing key validation in two locations within the patch application logic. In packages/jsondiffpatch/src/filters/nested.ts, the nested-object diff and patch filters iterated object children without excluding __proto__. In packages/jsondiffpatch/src/formatters/jsonpatch-apply.ts, the parsePathFromRFC6902 helper returned raw path segments that were then used as bracket-notation accessors during traversal, with no allowlist or denylist applied.
Attack Vector
An attacker who controls a delta document or a JSON Patch operation submitted to a vulnerable application can craft a payload with paths such as /__proto__/polluted or a delta keyed on constructor.prototype. When the application calls jsondiffpatch.patch() or the JSON Patch patch() API, the library walks the attacker-controlled segments and assigns the supplied value to Object.prototype. The attack requires no authentication when the receiving endpoint accepts JSON input from untrusted sources.
// Security patch in packages/jsondiffpatch/src/filters/nested.ts
import ReverseContext from "../contexts/reverse.js";
import type { ArrayDelta, Delta, Filter, ObjectDelta } from "../types.js";
+// '__proto__' must never be used as a property key — it bypasses normal
+// property assignment and directly modifies the object's prototype chain.
+// 'constructor' and 'prototype' are handled by the hasOwnProperty guard below
+// (we only traverse own properties of left, so inherited 'constructor' is
+// never followed into Object.prototype).
+const UNSAFE_KEYS = new Set(["__proto__"]);
+
export const collectChildrenDiffFilter: Filter<DiffContext> = (context) => {
if (!context || !context.children) {
return;
Source: jsondiffpatch commit 381c0125
// Security patch in packages/jsondiffpatch/src/formatters/jsonpatch-apply.ts
-const parsePathFromRFC6902 = (path: string) => {
- // see https://datatracker.ietf.org/doc/html/rfc6902#appendix-A.14
+const UNSAFE_KEYS = new Set(["__proto__", "constructor", "prototype"]);
+
+// see https://datatracker.ietf.org/doc/html/rfc6902#appendix-A.14
+function parsePathFromRFC6902(
+ path: string,
+ opts: { safe: false },
+): string[] | null;
+function parsePathFromRFC6902(path: string, opts?: { safe?: true }): string[];
+function parsePathFromRFC6902(
+ path: string,
+ { safe = true }: { safe?: boolean } = {},
+): string[] | null {
if (typeof path !== "string") return path;
if (path.substring(0, 1) !== "/") {
throw new Error("JSONPatch paths must start with '/'");
}
Source: jsondiffpatch commit 381c0125
The patch introduces an UNSAFE_KEYS allowlist filter and refactors parsePathFromRFC6902 to optionally reject paths containing reserved property names.
Detection Methods for CVE-2026-8657
Indicators of Compromise
- HTTP request bodies or JSON payloads containing __proto__, constructor, or prototype as JSON keys or as segments in RFC 6902 path fields such as /__proto__/....
- Unexpected properties appearing on unrelated objects at runtime, indicating that Object.prototype has been modified.
- Node.js process behavior changes such as new fields returned by JSON.stringify({}) containing keys not defined in source code.
Detection Strategies
- Inspect dependency manifests (package.json, package-lock.json, yarn.lock, pnpm-lock.yaml) for jsondiffpatch versions below 0.7.6.
- Add request-body inspection to API gateways or WAFs to flag JSON documents whose keys or path fields contain __proto__, constructor, or prototype.
- Run a startup assertion that checks Object.prototype for unexpected enumerable properties before and after processing untrusted input.
Monitoring Recommendations
- Log all calls to jsondiffpatch.patch() and jsonpatch.patch() along with the source IP and authenticated principal supplying the delta.
- Alert on application error spikes following deserialization of patch documents, which often follow successful prototype pollution.
- Track Software Composition Analysis (SCA) findings for the jsondiffpatch package and route them to the application owners responsible for ingesting external JSON.
How to Mitigate CVE-2026-8657
Immediate Actions Required
- Upgrade jsondiffpatch to version 0.7.6 or later in all production and development environments.
- Audit application code paths that pass user-supplied data into jsondiffpatch.patch() or jsondiffpatch/formatters/jsonpatch.patch().
- Reject any inbound JSON Patch document whose path contains __proto__, constructor, or prototype until the upgrade is deployed.
Patch Information
The fix is shipped in jsondiffpatch version 0.7.6. See the upstream fix in jsondiffpatch commit 381c0125 and the advisory at Snyk SNYK-JS-JSONDIFFPATCH-16322990. The patch adds an UNSAFE_KEYS set covering __proto__, constructor, and prototype, and rewrites parsePathFromRFC6902 to validate segments before traversal.
Workarounds
- Wrap calls to jsondiffpatch.patch() in a pre-processing step that recursively rejects any object containing keys equal to __proto__, constructor, or prototype.
- Freeze Object.prototype at application startup with Object.freeze(Object.prototype) to prevent any code path from mutating it.
- Run the Node.js process with --disable-proto=delete to remove the __proto__ accessor from Object.prototype entirely.
# Upgrade jsondiffpatch to the patched release
npm install jsondiffpatch@^0.7.6
# Verify the installed version
npm ls jsondiffpatch
# Harden the Node.js runtime against prototype-pollution exploitation
node --disable-proto=delete app.js
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


