scimPatch vulnerable to prototype pollution via unfiltered keys in patch
The `scim-patch` Node.js library, versions up to and including 0.9.0, is critically vulnerable to prototype pollution (CVE-2026-48170) when processing SCIM PATCH operations, allowing an attacker to modify `Object.prototype` process-wide through crafted `__proto__` keys in the request body, leading to potential privilege escalation or denial of service.
The scim-patch Node.js library, versions up to and including 0.9.0, is affected by a critical prototype pollution vulnerability, CVE-2026-48170. This flaw allows an unauthenticated or low-privileged attacker to achieve process-wide impact by sending a specially crafted SCIM PATCH request. The delivery mechanism involves a normal SCIM PATCH /Users/:id request body where the value object contains a key structured as __proto__.someProp. When the scimPatch() function processes this input, it inadvertently modifies Object.prototype in the Node.js runtime. This mutation affects every plain object within the running process, creating a persistent state until the process restarts. For defenders, this is critical because it can lead to severe consequences such as privilege escalation if authentication logic relies on checking properties of otherwise clean objects (e.g., req.user.isAdmin), or denial of service through logic bypasses, impacting the availability and integrity of services using scim-patch.
Attack Chain
- Attacker crafts a malicious SCIM PATCH request targeting a vulnerable endpoint, for example,
PATCH /Users/:id. - The request body contains a JSON array with an "add" or "replace" operation, where the
valueobject includes a key structured as__proto__.pollutedor__proto__.isAdmin. - The vulnerable Node.js application, using the
scim-patchlibrary, receives and processes this request via thescimPatch()function. - Inside
scimPatch(), theaddOrReplaceObjectAttributefunction iterates over the user-suppliedpatch.valueand feeds the dangerous key (__proto__.polluted) toresolvePaths. - The
assignhelper function then walks thekeyPathwhich includes__proto__, andobjis reassigned toObject.prototypewhenobj = obj["__proto__"]is executed. - Subsequently, the
valuefrom the malicious patch (e.g.,'yes'ortrue) is assigned toObject.prototype.pollutedorObject.prototype.isAdmin, effectively polluting the globalObject.prototype. - This global prototype modification persists until the Node.js process is restarted, affecting all subsequent operations and new objects within that process.
- This leads to impacts such as privilege escalation if downstream code checks for properties like
isAdminon affected objects, or denial of service through logic bypasses.
Impact
The impact of CVE-2026-48170 is process-wide, affecting any Node.js service utilizing the scim-patch library for SCIM operations. This could include identity management systems, user provisioning services, and enterprise applications that integrate with external Identity Providers (IdPs). If exploited, this prototype pollution can lead to severe consequences such as privilege escalation, enabling attackers to bypass authentication or authorization checks if affected code relies on checking properties of otherwise clean objects (e.g., req.user.isAdmin). It can also cause denial of service through logic bypasses if critical application logic branches on object properties, leading to unpredictable behavior or crashes. The modification to Object.prototype persists until the Node.js process is restarted, affecting every request handled by the compromised container after pollution, making detection and recovery challenging.
Recommendation
- Upgrade the
npm/scim-patchlibrary to a version beyond0.9.0(which includes the fix for CVE-2026-48170) immediately. - Implement
Object.freeze(Object.prototype)at the Node.js process startup to mitigate CVE-2026-48170, as described in the brief's "Mitigation" section. - Utilize the Node.js
--frozen-intrinsicsflag during process startup to automatically protect built-in objects from prototype pollution, which helps mitigate CVE-2026-48170.