CVE-2021-25914
Description
Prototype pollution in object-collider <=1.0.3 allows denial of service and potential remote code execution via crafted objects.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Prototype pollution in object-collider <=1.0.3 allows denial of service and potential remote code execution via crafted objects.
Vulnerability
CVE-2021-25914 describes a prototype pollution vulnerability in the object-collider library, affecting versions 1.0.0 through 1.0.3. The flaw originates in the collideObjects function, which merges object properties without filtering the __proto__ key. This allows an attacker to pollute the base Object.prototype by injecting malicious properties through a crafted object [1][2].
Exploitation
The vulnerability can be triggered by passing user-controlled data to the collision functions, such as collideUnsafe. No authentication is required if the library is used on untrusted input. An attacker can craft a JSON object containing "__proto__" with arbitrary sub-properties. When merged, those properties are assigned to Object.prototype, affecting all subsequent objects in the runtime [2][3].
Impact
Successful exploitation leads to prototype pollution, which can cause denial of service by overriding critical properties (e.g., toString, constructor) or by injecting properties that enable further attacks. Under certain conditions, this can escalate to remote code execution if the polluted properties are used in security-sensitive operations [1][3].
Mitigation
The fix was implemented in commit 321f75a7f8e7b3393e5b7dd6dd9ab26ede5906e5, which explicitly skips the __proto__ key during object merging [2]. Users should upgrade to version 1.0.4 or later. No workaround is available; patching the library directly is the recommended action.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
object-collidernpm | >= 1.0.0, < 1.0.4 | 1.0.4 |
Affected products
2- object-collider/object-colliderdescription
Patches
1321f75a7f8e7fix: __proto__ property merge
2 files changed · +44 −22
src/utils/CollideUtil.ts+9 −8 modified@@ -25,7 +25,7 @@ export function collide(arg1: any, arg2: any, modifiers?: ICollideModifiers, sta * @param startPath the entry path to start modifier path generation. Default value: $ * @returns collide result */ -export function collideUnsafe(arg1: any, arg2: any, modifiers?: ICollideModifiers, startPath: string = '$'): any { +export function collideUnsafe(arg1: any, arg2: any, modifiers?: ICollideModifiers, startPath = '$'): any { if (arg2 === undefined) { return arg1; } @@ -78,14 +78,15 @@ function collideObjects(obj1: any, obj2: any, path: string, modifiers?: ICollide for (const key of Object.keys(obj2)) { const subPath = path + '.' + key; - - if (obj1[key] === undefined) { - obj1[key] = obj2[key]; - } else { - if (modifiers && modifiers[subPath]) { - obj1[key] = modifiers[subPath](obj1[key], obj2[key]); + if (key !== '__proto__') { + if (obj1[key] === undefined) { + obj1[key] = obj2[key]; } else { - obj1[key] = collideUnsafe(obj1[key], obj2[key], modifiers, subPath); + if (modifiers && modifiers[subPath]) { + obj1[key] = modifiers[subPath](obj1[key], obj2[key]); + } else { + obj1[key] = collideUnsafe(obj1[key], obj2[key], modifiers, subPath); + } } } }
test/unit/CollideUtilTestSuite.ts+35 −14 modified@@ -62,20 +62,17 @@ class CollideUtilTestSuite { override: 11, }; - collideUnsafe( - obj1, - { - array: [3, 4], - obj: { - b: false, - d: 'd', - e: 1, - n: null, - array: [12, 13, 14], - }, - override: 111, + collideUnsafe(obj1, { + array: [3, 4], + obj: { + b: false, + d: 'd', + e: 1, + n: null, + array: [12, 13, 14], }, - ); + override: 111, + }); assert.deepStrictEqual(obj1, { array: [1, 2, 3, 4], @@ -164,7 +161,7 @@ class CollideUtilTestSuite { '#.custom.obj': (a: any, b: any) => Object.assign(a, b), '#.custom.override': (a: any) => a, }, - '#.custom' + '#.custom', ); assert.deepStrictEqual(result, { @@ -259,4 +256,28 @@ class CollideUtilTestSuite { collide({ a: [1, 2] }, { a: true }); }).to.throw('Unable to collide. Collide value at path $.a is not an array.'); } + + @test() + async testWithPrototypePollution(): Promise<void> { + const collideWith = JSON.parse(`{ + "__proto__": { + "vulnerable": "yes" + }, + "array": [3, 4] + }`); + + console.log(collideWith); + + const result = collide( + { + array: [1, 2], + }, + collideWith, + ); + + assert.ok(!result.vulnerable); + assert.deepStrictEqual(result, { + array: [1, 2, 3, 4], + }); + } }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-85g2-29m8-qf2pghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-25914ghsaADVISORY
- github.com/FireBlinkLTD/object-collider/commit/321f75a7f8e7b3393e5b7dd6dd9ab26ede5906e5ghsax_refsource_MISCWEB
- www.whitesourcesoftware.com/vulnerability-database/CVE-2021-25914ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.