{
  "ticket_id": "CVE-2026-8657",
  "code_root": "external/jsondiffpatch",
  "source": {
    "type": "cve",
    "cve_id": "CVE-2026-8657",
    "vendor": "benjamine",
    "product": "jsondiffpatch",
    "repo": "https://github.com/benjamine/jsondiffpatch"
  },
  "facts": {
    "cve_id": "CVE-2026-8657",
    "issue_summary": "Prototype pollution in jsondiffpatch's patch operation. jsondiffpatch.patch() and the jsonpatch formatter's patch() apply a delta/patch by traversing the target object using attacker-controlled property names and path segments. Through 0.7.5 they do not block dangerous segments such as __proto__ or constructor.prototype. A crafted delta whose path targets __proto__ makes patch() walk from the target object into Object.prototype and assign an attacker-chosen value to it, polluting the global prototype for the entire Node.js process.",
    "vulnerability_type": "Prototype Pollution (CWE-1321)",
    "suspected_cwe": ["CWE-1321"],
    "affected_versions": "< 0.7.6",
    "fixed_versions": ["0.7.6"],
    "reproduce_version": "0.7.5",
    "verify_fixed_version": "0.7.6",
    "repo_url": "https://github.com/benjamine/jsondiffpatch.git",
    "fix_commit": "381c0125efab49f6f0dbc08317d01d55717672af",
    "code_root": "external/jsondiffpatch",
    "ecosystem": "npm",
    "package": "jsondiffpatch",
    "affected_functions": ["jsondiffpatch.patch()", "jsonpatch formatter patch()"],
    "install_recipe": "In a scratch directory run `npm install jsondiffpatch@0.7.5` (vulnerable) or `npm install jsondiffpatch@0.7.6` (fixed). The published npm tarball is the canonical artifact; git tags v0.7.5 / v0.7.6 on the repo are equivalent.",
    "attacker_access": "Any code path that forwards an attacker-influenced delta or JSON patch into jsondiffpatch.patch() or the jsonpatch formatter's patch() (e.g. a delta deserialized from untrusted JSON request input).",
    "exploit_outline": "Build a crafted delta that, when applied with patch(), targets the __proto__ property of the target object and assigns a value to a child property. patch() traverses obj['__proto__'] (the live Object.prototype) and writes the attacker-chosen value onto it.",
    "vulnerable_indicator": "After applying the crafted delta with patch() on 0.7.5, a freshly created plain object `({})` carries the injected property (e.g. `({}).polluted === '<attacker value>'`), proving Object.prototype was polluted.",
    "fixed_indicator": "In 0.7.6 patch() rejects/ignores the dangerous __proto__ path segment; after applying the same delta, `({}).polluted` is still `undefined` and Object.prototype is unchanged.",
    "reproduction_requirements": "Node.js (any maintained LTS) plus the jsondiffpatch package at the specified version. No network service, database, browser, or OS-specific behavior required - the difference is observable purely in-process.",
    "notes": "Both jsondiffpatch.patch() and the jsonpatch formatter's patch() share the same root cause: path traversal over attacker-controlled segments without blocking __proto__ / constructor.prototype. The fix commit 381c0125efab49f6f0dbc08317d01d55717672af adds guards against these dangerous segments. The PoC must apply a crafted delta via patch() so it pollutes Object.prototype on 0.7.5 and is blocked on 0.7.6."
  }
}
