Convict Prototype Pollution via String.prototype.startsWith Override
Convict 6.2.4 contains a prototype pollution flaw where attackers can override String.prototype.startsWith to bypass validation checks, enabling Object.prototype contamination. The PoC demonstrates that previous mitigation attempts are insufficient and defenders must implement input validation at multiple layers.
CVE References
Affected
Vulnerability Description
This is a prototype pollution vulnerability classified as a dangerous object manipulation attack. The root cause stems from reliance on String.prototype.startsWith() as a security boundary to block forbidden property paths (e.g., constructor, prototype). Prototype pollution allows attackers to inject properties into Object.prototype, affecting all objects in the JavaScript runtime. The impact is severe: downstream applications may experience unauthorized property injection affecting business logic, security checks, or default values.
PoC Significance for Defenders
The PoC demonstrates a second-order bypass where the attacker doesn't directly craft malicious input, but instead poisons the String prototype mechanism itself before convict validation runs. This proves:
- The previous patch was insufficient (likely added a simple string check)
- The vulnerability assumes stable built-in method behavior
- Exploitation requires application initialization order control or shared execution context
- The attacker-controlled key path reaches dangerous prototype chains
The precondition (ability to execute code before convict loads) is realistic in monolithic applications, build tools, or scenarios where untrusted modules load in sequence.
Detection Guidance
Runtime Detection:
- Monitor for
Object.definePropertyorObject.prototypemutations after convict initialization - Log attempts to set properties on
constructororprototypechains viaconvict.set() - Audit application logs for configuration keys matching patterns:
constructor.*,__proto__,prototype.*
Static Analysis:
- Scan for
convict().set()calls with dynamic/user-supplied keys - Flag applications pinned to convict versions <= 6.2.4
- Search dependency trees for convict in critical infrastructure (configuration servers, secret managers)
Signature Pattern:
Key path contains: ['constructor', 'prototype', '__proto__'] OR
String.prototype overrides precede convict require()
Mitigation Steps
- Patch: Upgrade convict to > 6.2.4 once released (ensure fix uses object property checks, not string methods)
- Input Validation (Defense-in-Depth):
- Implement explicit allowlist of permitted configuration keys
- Validate key paths match expected schema before passing to convict
- Reject any keys containing
constructor,__proto__,prototype
- Workaround: Freeze Object.prototype and String.prototype at application startup
- Code Review: Audit all
config.set()calls—never pass unsanitized user input as keys - Config Management Best Practice: Use separate, immutable configuration objects; avoid dynamic property injection
Risk Assessment
Likelihood: Medium-to-High in real-world applications. Convict is widely used in Node.js configuration management. Exploitation requires:
- Application accepting dynamic config keys (e.g., environment variables, API input)
- Attack surface exists if config schema is not strictly validated upstream
Threat Actor Interest: High. Prototype pollution is a well-known attack enabling RCE, privilege escalation, or service disruption. Nation-state and organized cybercriminal groups actively exploit configuration management flaws. Organizations using convict for multi-tenant systems or API configuration are at elevated risk.
Sources