CVE-2026-33863
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-33863 is a prototype pollution vulnerability in the convict npm package (mozilla/node-convict) affecting all versions up to and including 6.2.4. It exposes two unguarded pollution paths not addressed by prior fixes: recursive merging in config.load() / config.loadFile() via the overlay() function, and default-value propagation during schema initialization in convict({...}). The vulnerability was reported on October 4, 2025, published to the GitHub Advisory Database on March 26, 2026, and has a CVSS v4 base score of 9.4 (Critical) (GitHub Advisory). A patch was released in version 6.2.5 (GitHub Advisory).

Technical details

The root cause is CWE-1321 (Improperly Controlled Modification of Object Prototype Attributes), manifesting through two distinct code paths (GitHub Advisory). First, the overlay() function used by config.load() and config.loadFile() performs recursive merging of configuration data without filtering forbidden keys such as __proto__ or constructor.prototype; supplying a crafted JSON file with these keys causes the recursion to traverse into Object.prototype and write attacker-controlled values globally. Second, during schema initialization, if a schema object passed to convict({...}) contains constructor.prototype.* keys, the addDefaultValues routine walks into the built-in Object function and its prototype, writing default values directly to Object.prototype at startup — before any string-path filtering can intervene (node-convict Issue #423). A prior fix in the set() path used startsWith() to block forbidden keys, but this check was not applied to the overlay() and schema initialization paths, leaving them unguarded (GitHub Advisory).

Impact

Successful exploitation pollutes Object.prototype globally within the Node.js process, meaning every plain object in the application inherits the attacker-injected properties. Depending on how downstream code consumes these properties, the impact ranges from unexpected application behavior and denial of service to authentication bypass (e.g., injecting a property that a security check reads from a plain object) or remote code execution if polluted properties reach dangerous sinks such as eval, child_process.exec, or template engines (GitHub Advisory, node-convict Issue #423). Both the vulnerable system and subsequent systems that share the same process or depend on the polluted runtime state are affected, with high confidentiality, integrity, and availability impact scores (GitHub Advisory).

Exploitability

A public proof-of-concept is available in the GitHub issue tracker, demonstrating that passing a schema with constructor.prototype.polluted keys to convict() causes ({}).polluted to return the attacker-supplied value (node-convict Issue #423). No privileges are required and no user interaction is needed; the attack vector is local (the attacker must be able to supply input to load(), loadFile(), or convict()), with low attack complexity (GitHub Advisory). No in-the-wild exploitation, threat actor attribution, EPSS score, or CISA KEV catalog listing has been reported as of the available data.

Exploitation steps

  1. Identify the attack surface: Determine whether the target Node.js application uses convict ≤ 6.2.4 and passes any externally influenced data (e.g., user-uploaded JSON files, environment-derived config objects) to config.load(), config.loadFile(), or convict({...}).
  2. Craft a malicious payload for load()/loadFile(): Prepare a JSON configuration file or object containing a forbidden key path, for example:
    { "__proto__": { "polluted": "pwned" } }
    or equivalently using constructor.prototype:
    { "constructor": { "prototype": { "polluted": "pwned" } } }
  3. Trigger the vulnerable merge: Cause the application to call config.load(<malicious_object>) or config.loadFile(<path_to_malicious_json>). The overlay() function recursively merges the data without key filtering, writing the attacker value to Object.prototype.
  4. Alternatively, exploit schema initialization: Supply a schema object with constructor.prototype.* keys to convict({...}) at startup:
    convict({ constructor: { prototype: { polluted: 'pwned!' } } });
    The addDefaultValues routine propagates defaults into Object.prototype before any path-based checks run (node-convict Issue #423).
  5. Leverage the polluted property: After pollution, every plain object in the process inherits the injected property. Target application logic that reads properties from plain objects for security decisions (e.g., if (req.user.isAdmin)) or that passes object properties to dangerous sinks (e.g., child_process.exec, eval) to escalate to authentication bypass or RCE (GitHub Advisory).

Indicators of compromise

  • Logs: Unexpected properties appearing on plain objects in application debug logs or error stack traces; Node.js process errors referencing Object.prototype modifications or unexpected property values on {}.
  • File System: Presence of JSON configuration files containing keys __proto__, constructor, or prototype at the top level or nested within config data supplied to the application.
  • Process Behavior: Unusual child processes spawned by the Node.js application (e.g., sh, bash, cmd.exe) if polluted properties reach child_process sinks; application authentication logic returning unexpected results (e.g., unauthenticated users gaining elevated access).
  • Dependency Audit: npm audit or npm list convict output showing convict version ≤ 6.2.4 installed in the project (GitHub Advisory).

Mitigation and workarounds

Upgrade the convict npm package to version 6.2.5 or later, which contains the fix for both unguarded prototype pollution paths (GitHub Advisory). As an immediate workaround where upgrading is not possible, do not pass untrusted or externally controlled data to config.load(), config.loadFile(), or convict() — validate and sanitize all input to ensure it does not contain __proto__, constructor, or prototype keys before passing it to these functions (GitHub Advisory). Additionally, consider using Object.freeze(Object.prototype) at application startup as a defense-in-depth measure to prevent prototype pollution from any source, though this may break libraries that rely on prototype extension.

Community reactions

The vulnerability was discovered and reported by researcher selenop via GitHub issue #423 on October 4, 2025, and the advisory was published by toufali on March 24, 2026, with clouserw serving as remediation reviewer (node-convict Issue #423, GitHub Advisory). The issue is part of a recurring pattern of prototype pollution bypasses in convict, with this CVE explicitly noted as not covered by the prior fix (GHSA-44fc-8fm5-q62h / CVE-2026-33864) (GitHub Advisory). No broader media coverage or notable social media reactions have been identified in the available data.

Additional resources


SourceThis report was generated using AI

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-59160HIGH8.8
  • JavaScript logoJavaScript
  • @yeger/turbo-graph
NoYesSep 09, 2026
CVE-2026-59179HIGH8.3
  • JavaScript logoJavaScript
  • @openhop/server
NoYesSep 09, 2026
GHSA-x7m8-jrm8-hpvxHIGH8.1
  • JavaScript logoJavaScript
  • @eigenpal/docx-editor-core
NoYesSep 10, 2026
CVE-2026-59176HIGH7.8
  • JavaScript logoJavaScript
  • functype-mcp-server
NoYesSep 09, 2026
CVE-2026-59158HIGH7.5
  • JavaScript logoJavaScript
  • nuxt-ollama
NoYesSep 09, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management