The Ouroboros Bug: How set-in's Security Check Ate Itself
Vulnerability ID: CVE-2026-26021
CVSS Score: 9.4
Published: 2026-02-11
A critical prototype pollution vulnerability in the set-in npm package exposes a fundamental misunderstanding of JavaScript's mutable environment. The library attempted to blacklist dangerous keys like __proto__ and constructor to prevent pollution, but it implemented this check using Array.prototype.includes. In a hostile environment—or via a prior gadget—an attacker can monkey-patch this method to always return false, effectively turning off the security camera before robbing the bank. This allows arbitrary property injection into the global Object.prototype, leading to Denial of Service (DoS) or Remote Code Execution (RCE).
TL;DR
The set-in library used a mutable global method (.includes()) to validate input against prototype pollution. Attackers can hijack this method to bypass the check, allowing full prototype pollution.
⚠️ Exploit Status: POC
Technical Details
- CWE ID: CWE-1321
- Attack Vector: Local (via library usage)
- CVSS Score: 9.4 (Critical)
- Affected Versions: < 2.0.5
- Exploit Status: PoC Available
- Patch: Commit b8e1dab
Affected Systems
- Node.js applications using set-in < 2.0.5
- Frontend applications (React/Vue/Angular) using set-in for state management
-
set-in: >= 2.0.1, < 2.0.5 (Fixed in:
2.0.5)
Code Analysis
Commit: b8e1dab
Fix prototype pollution by replacing .includes with equality check
- assert.ok(!POLLUTED_KEYS.includes(key), ...)
+ if(key == "constructor" || key == "prototype" || key == "__proto__"){
+ throw `setIn: ${key} is disallowed...`
+ }
Exploit Details
- Internal Research: PoC demonstrating Array.prototype.includes hijack to bypass security check
Mitigation Strategies
- Upgrade to set-in v2.0.5+
- Freeze global prototypes (Object.freeze, Array.freeze)
- Use Map instead of Object for user-controlled keys
- Input validation using schema libraries (Zod, Joi)
Remediation Steps:
- Identify usage of
set-inin package.json/package-lock.json. - Run
npm install set-in@2.0.5to update the dependency. - Audit code for other libraries using
Array.prototype.includesfor security checks. - Implement a post-install script or runtime check to ensure prototypes are frozen in production.
References
Read the full report for CVE-2026-26021 on our website for more details including interactive diagrams and full exploit analysis.
Top comments (0)