Prototype Pollution in overmind
Summary
overmind (<= 28.2.1) is vulnerable to Prototype Pollution via the rehydrate function.
Description
The rehydrate() function recursively copies properties from a source state object to a target without filtering __proto__ keys. In a state management library like Overmind, rehydrate is used to restore serialized state — if that state comes from an untrusted source (e.g., SSR hydration, localStorage), an attacker can inject __proto__ properties.
Proof of Concept
const { rehydrate } = require("overmind");
console.log("Before:", ({}).polluted); // undefined
const malicious = JSON.parse('{"__proto__":{"polluted":"yes"}}');
rehydrate({}, malicious);
console.log("After:", ({}).polluted); // "yes"
const fresh = {};
console.log("fresh.polluted:", fresh.polluted); // "yes"
Why this is a real vulnerability
Object.prototype is globally modified — after the PoC runs, ({}).polluted === "yes" on every newly created object in the entire Node.js process
- The pollution is silent — no error is thrown, no warning is logged. The caller has no indication that the global prototype was modified
- Any downstream code is affected — authentication checks (
if (user.isAdmin)), serialization, template rendering, database queries — all inherit the polluted properties
- This is a well-documented vulnerability class with numerous CVEs assigned for the same pattern: CVE-2020-8203 (lodash), CVE-2021-25945 (js-extend)
Impact
- Remote Code Execution (RCE) —
child_process.spawn inherits shell: true from polluted prototype
- Denial of Service (DoS) — overriding
toString/valueOf crashes string coercion
- Authentication Bypass — polluting
isAdmin/role/authorized properties
- Property Injection — all objects inherit polluted properties
Remediation
Filter dangerous keys during recursive object traversal:
const UNSAFE_KEYS = new Set(["__proto__", "constructor", "prototype"]);
// Add this check in the recursive merge loop:
if (UNSAFE_KEYS.has(key)) continue;
References
Prototype Pollution in
overmindSummary
overmind(<= 28.2.1) is vulnerable to Prototype Pollution via therehydratefunction.Description
The
rehydrate()function recursively copies properties from a source state object to a target without filtering__proto__keys. In a state management library like Overmind,rehydrateis used to restore serialized state — if that state comes from an untrusted source (e.g., SSR hydration, localStorage), an attacker can inject__proto__properties.Proof of Concept
Why this is a real vulnerability
Object.prototypeis globally modified — after the PoC runs,({}).polluted === "yes"on every newly created object in the entire Node.js processif (user.isAdmin)), serialization, template rendering, database queries — all inherit the polluted propertiesImpact
child_process.spawninheritsshell: truefrom polluted prototypetoString/valueOfcrashes string coercionisAdmin/role/authorizedpropertiesRemediation
Filter dangerous keys during recursive object traversal:
References