Prototype Pollution
Description
Convict configuration library before 6.2.2 allows prototype pollution via the convict function due to incomplete validation of parentKey.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Convict configuration library before 6.2.2 allows prototype pollution via the `convict` function due to incomplete validation of `parentKey`.
Vulnerability
The convict package, a configuration management library for Node.js, is vulnerable to Prototype Pollution in versions before 6.2.2. The vulnerability resides in the convict function itself, which fails to properly validate the parentKey parameter. This allows an attacker to inject properties into the JavaScript Object.prototype. The issue is an incomplete fix of a prior vulnerability [SNYK-JS-CONVICT-1062508], as described in the advisory [1], [2].
Exploitation
An attacker can exploit this vulnerability by crafting a configuration object that includes a property with a __proto__ path. For example, by calling config.set('__proto__.polluted', 'Yes! Its Polluted') on a convict instance [4]. The attacker does not need special privileges beyond the ability to supply configuration data to the application. User interaction is required only if the configuration is loaded from an untrusted source that the user processes.
Impact
Successful exploitation leads to Prototype Pollution, where properties are injected into Object.prototype. This can result in information disclosure, denial of service, or remote code execution, depending on how the polluted properties are used by the application [2]. The attacker can alter the behavior of all objects in the runtime environment [2], [4].
Mitigation
The vulnerability is fixed in convict version 6.2.2, released on 2021-12-19 [3], [4]. Users should upgrade to version 6.2.2 or later immediately. There is no known workaround. The fix prevents modification of the object prototype [4].
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 |
|---|---|---|
convictnpm | < 6.2.3 | 6.2.3 |
Affected products
2- Range: v0.2.0, v0.2.1, v0.2.2, …
Patches
13b86be087d8fMore complete fix against prototype pollution
2 files changed · +48 −7
packages/convict/src/main.js+17 −7 modified@@ -9,6 +9,15 @@ const fs = require('fs') const parseArgs = require('yargs-parser') const cloneDeep = require('lodash.clonedeep') +// Forbidden key paths, for protection against prototype pollution +const FORBIDDEN_KEY_PATHS = [ + '__proto__', + 'this.constructor.prototype', +] + +const ALLOWED_OPTION_STRICT = 'strict' +const ALLOWED_OPTION_WARN = 'warn' + function assert(assertion, err_msg) { if (!assertion) { throw new Error(err_msg) @@ -69,9 +78,6 @@ const custom_converters = new Map() const parsers_registry = {'*': JSON.parse} -const ALLOWED_OPTION_STRICT = 'strict' -const ALLOWED_OPTION_WARN = 'warn' - function flatten(obj, useProperties) { const stack = Object.keys(obj) let key @@ -561,14 +567,18 @@ const convict = function convict(def, opts) { * exist, they will be initialized to empty objects */ set: function(k, v) { + for (const path of FORBIDDEN_KEY_PATHS) { + if (k.startsWith(`${path}.`)) { + return this + } + } + v = coerce(k, v, this._schema, this) const path = k.split('.') const childKey = path.pop() const parentKey = path.join('.') - if (!(parentKey == '__proto__' || parentKey == 'constructor' || parentKey == 'prototype')) { - const parent = walk(this._instance, parentKey, true) - parent[childKey] = v - } + const parent = walk(this._instance, parentKey, true) + parent[childKey] = v return this },
packages/convict/test/prototype_pollution.test.js+31 −0 added@@ -0,0 +1,31 @@ +'use strict' + +const convict = require('../') + +describe('Convict prototype pollution resistance', function() { + + test('against __proto__', function() { + const obj = {} + const config = convict(obj) + + config.set('__proto__.polluted_proto_root', 'Polluted!') + expect({}).not.toHaveProperty('polluted_proto_root') + + config.set('__proto__.nested.polluted_proto_nested', 'Polluted!') + expect({}).not.toHaveProperty('nested') + expect({}).not.toHaveProperty('nested.polluted_proto_nested') + }) + + test('against this.constructor.prototype', function() { + const obj = {} + const config = convict(obj) + + config.set('this.constructor.prototype.polluted_constructor_prototype_root', 'Polluted!') + expect({}).not.toHaveProperty('polluted_constructor_prototype_root') + + config.set('this.constructor.prototype.nested.polluted_constructor_prototype_nested', 'Polluted!') + expect({}).not.toHaveProperty('nested') + expect({}).not.toHaveProperty('nested.polluted_constructor_prototype_nested') + }) + +})
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
9- github.com/advisories/GHSA-x2w5-725j-gf2gghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-22143ghsaADVISORY
- github.com/mozilla/node-convict/blob/5eb1314f85346760a3c31cb14510f2f0af11d0d3/packages/convict/src/main.js%23L569ghsax_refsource_MISCWEB
- github.com/mozilla/node-convict/commit/3b86be087d8f14681a9c889d45da7fe3ad9cd880ghsax_refsource_MISCWEB
- github.com/mozilla/node-convict/pull/384ghsaWEB
- github.com/mozilla/node-convict/releases/tag/v6.2.2ghsaWEB
- github.com/mozilla/node-convict/security/advisories/GHSA-x2w5-725j-gf2gghsaWEB
- snyk.io/vuln/SNYK-JS-CONVICT-2340604ghsax_refsource_MISCWEB
- www.huntr.dev/bounties/1-npm-convictghsaWEB
News mentions
0No linked articles in our index yet.