VYPR
Critical severityOSV Advisory· Published May 13, 2022· Updated Sep 17, 2024

Prototype Pollution

CVE-2022-21190

Description

Convict before 6.2.3 allows prototype pollution bypass via prepending dangerous paths with arbitrary string and dot.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Convict before 6.2.3 allows prototype pollution bypass via prepending dangerous paths with arbitrary string and dot.

Vulnerability

This vulnerability affects the convict package before version 6.2.3. It is a bypass of the incomplete fix for CVE-2022-22143. The earlier fix checked if a key path starts with __proto__ or this.constructor.prototype using startsWith. However, an attacker can prepend any string followed by a dot (e.g., foo.__proto__ or foo.this.constructor.prototype) to bypass the check, allowing prototype pollution through the set method [1][4].

Exploitation

An attacker needs the ability to call the set method on a convict configuration object with a crafted key path. No special network position or authentication is required if the application exposes this functionality. The attacker supplies a key like foo.__proto__.polluted and a value; the set method splits the path on dots and walks the object tree, ultimately assigning the value to the prototype chain [4].

Impact

Successful exploitation leads to prototype pollution, which can result in denial of service, remote code execution, or cross-site scripting depending on the application context [3]. The attacker can inject properties into Object.prototype, affecting all objects in the runtime.

Mitigation

Upgrade to convict version 6.2.3 or later, released on 2022-05-07 [2]. The fix extends the forbidden key paths to include a trailing dot and checks both startsWith and includes for .-prefixed forbidden paths [2]. No workaround is available for earlier versions.

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.

PackageAffected versionsPatched versions
convictnpm
< 6.2.36.2.3

Affected products

2

Patches

1
1ea0ab19c520

More more complete fix for prototype pollution

https://github.com/mozilla/node-convictMarc-Aurèle DARCHEMay 7, 2022via ghsa
3 files changed · +41 4
  • CHANGELOG.md+8 0 modified
    @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
     and this project adheres to [Semantic Versioning](http://semver.org/).
     
     
    +## [6.2.3] - 2022-05-07
    +
    +### Fixed
    +
    +- More more complete fix for prototype pollution vulnerability first addressed
    +  in #384 (Marc-Aurèle Darche @madarche, Snyk Security team)
    +
    +
     ## [6.2.2] - 2022-03-27
     
     ### Fixed
    
  • packages/convict/src/main.js+5 4 modified
    @@ -11,8 +11,8 @@ const cloneDeep = require('lodash.clonedeep')
     
     // Forbidden key paths, for protection against prototype pollution
     const FORBIDDEN_KEY_PATHS = [
    -  '__proto__',
    -  'this.constructor.prototype',
    +  '__proto__.',
    +  'this.constructor.prototype.',
     ]
     
     const ALLOWED_OPTION_STRICT = 'strict'
    @@ -567,8 +567,9 @@ 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}.`)) {
    +      for (const forbidden_key_path of FORBIDDEN_KEY_PATHS) {
    +        if (k.startsWith(forbidden_key_path) ||
    +            k.includes(`.${forbidden_key_path}`)) {
               return this
             }
           }
    
  • packages/convict/test/prototype_pollution.test.js+28 0 modified
    @@ -14,6 +14,20 @@ describe('Convict prototype pollution resistance', function() {
         config.set('__proto__.nested.polluted_proto_nested', 'Polluted!')
         expect({}).not.toHaveProperty('nested')
         expect({}).not.toHaveProperty('nested.polluted_proto_nested')
    +
    +    config.set('this.__proto__.polluted_proto_root', 'Polluted!')
    +    expect({}).not.toHaveProperty('polluted_proto_root')
    +
    +    config.set('this.__proto__.nested.polluted_proto_nested', 'Polluted!')
    +    expect({}).not.toHaveProperty('nested')
    +    expect({}).not.toHaveProperty('nested.polluted_proto_nested')
    +
    +    config.set('foo.__proto__.polluted_proto_root', 'Polluted!')
    +    expect({}).not.toHaveProperty('polluted_proto_root')
    +
    +    config.set('foo.__proto__.nested.polluted_proto_nested', 'Polluted!')
    +    expect({}).not.toHaveProperty('nested')
    +    expect({}).not.toHaveProperty('nested.polluted_proto_nested')
       })
     
       test('against this.constructor.prototype', function() {
    @@ -26,6 +40,20 @@ describe('Convict prototype pollution resistance', function() {
         config.set('this.constructor.prototype.nested.polluted_constructor_prototype_nested', 'Polluted!')
         expect({}).not.toHaveProperty('nested')
         expect({}).not.toHaveProperty('nested.polluted_constructor_prototype_nested')
    +
    +    config.set('this.this.constructor.prototype.polluted_constructor_prototype_root', 'Polluted!')
    +    expect({}).not.toHaveProperty('polluted_constructor_prototype_root')
    +
    +    config.set('this.this.constructor.prototype.nested.polluted_constructor_prototype_nested', 'Polluted!')
    +    expect({}).not.toHaveProperty('nested')
    +    expect({}).not.toHaveProperty('nested.polluted_constructor_prototype_nested')
    +
    +    config.set('foo.this.constructor.prototype.polluted_constructor_prototype_root', 'Polluted!')
    +    expect({}).not.toHaveProperty('polluted_constructor_prototype_root')
    +
    +    config.set('foo.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

7

News mentions

0

No linked articles in our index yet.