CVE-2026-26021 – set-in (npm) – Prototype Pollution
CVE ID: CVE-2026-26021
Package: set-in (npm)
Vulnerability Type: Prototype Pollution
Affected Versions: >= 2.0.1 and < 2.0.5
Fixed Version: 2.0.5
CVSS v3.1: 9.8 (Critical)
Severity: Critical
Attack Vector: Network
Privileges Required: None
User Interaction: None
Exploitability: High
Exploit Availability: Technical details publicly discussed; proof-of-concept techniques demonstrated in security research context
Official Patch / Upgrade Link:
https://github.com/ahdinosaur/set-in/security/advisories/GHSA-2c4m-g7rx-63q7
Overview
CVE-2026-26021 is a critical prototype pollution vulnerability identified in the set-in npm package. The issue affects versions from 2.0.1 up to but not including 2.0.5. The flaw allows manipulation of JavaScript object prototypes when attacker-controlled input is processed without sufficient protection.
The vulnerability arises from improper handling of path validation logic. The library attempted to block dangerous keys such as __proto__ and constructor, but the protection mechanism relied on JavaScript built-in array methods in a way that could be bypassed. Under specific crafted conditions, the validation could be tricked, allowing writes to Object.prototype.
When Object.prototype is modified, every object created afterward inherits the polluted property. That behavior can have far-reaching impact across the entire application runtime.
Technical Details
The set-in library is designed to set values inside nested JavaScript objects using an array of path segments. Example behavior:
setIn(obj, ["user", "profile", "name"], "Alice")
To prevent prototype pollution, earlier fixes blocked path segments containing dangerous keys such as:
__proto__constructorprototype
However, the internal check relied on array prototype methods for validation. If the attacker manipulated or influenced the evaluation of those methods, the security check could be bypassed. Once bypassed, set-in would proceed to assign properties directly onto Object.prototype.
The flaw does not require authentication and can be triggered remotely if untrusted input flows into the vulnerable function.
Impact
The impact depends on how the affected application uses objects created after the pollution occurs.
Possible consequences include:
- Global property injection affecting all objects
- Authentication bypass if security checks rely on object properties
- Authorization manipulation
- Application logic corruption
- Denial of service due to unexpected type changes
- Remote code execution in edge cases where polluted properties reach dangerous execution sinks (e.g., dynamic function evaluation or process spawning)
Prototype pollution often becomes a stepping stone to deeper compromise rather than the final stage.
Exploitation Scenario (Educational)
For educational understanding only:
- An application accepts JSON input from a user.
- The JSON structure is converted into an array of keys.
- The array is passed into
set-in. - The validation mechanism fails to correctly block a malicious path segment.
- A property is written into
Object.prototype. - Subsequent objects inherit the malicious property.
A typical malicious payload pattern (non-executable example):
{
"path": ["__proto__", "isAdmin"],
"value": true
}
If processed by vulnerable logic, every object may inherit isAdmin = true. If authorization checks rely on that property without strict ownership validation, privilege escalation becomes possible.
Public discussions of proof-of-concept techniques exist in security communities. Functional exploit scripts are intentionally not reproduced here.
Attack Preconditions
- The application must use
set-inwith untrusted user input. - Input validation must be insufficient.
- Objects created later in the application lifecycle must rely on inherited properties.
If set-in is used only with trusted internal input, risk exposure decreases significantly.
MITRE Mapping
CWE: CWE-1321 – Improperly Controlled Modification of Object Prototype Attributes (‘Prototype Pollution’)
Relevant ATT&CK Techniques (Impact-Oriented):
- T1190 – Exploit Public-Facing Application
- T1068 – Exploitation for Privilege Escalation
- T1499 – Endpoint Denial of Service (conditional)
- T1059 – Command and Scripting Interpreter (if escalation leads to execution)
Prototype pollution acts as a technique enabler rather than a direct execution method.
Indicators of Exploitation
The following behavioral signs may indicate attempted or successful exploitation:
- HTTP request bodies containing:
__proto__constructorprototype
- Sudden unexpected boolean flags appearing in objects
- Authorization anomalies without database changes
- Type errors referencing overridden core methods
- Unusual crashes after processing specific requests
- Elevated privileges observed without legitimate role assignment
Log Sources for Detection
- Web server access logs
- Application request payload logs
- Node.js application logs
- API gateway logs
- WAF logs
- Container runtime logs
- APM trace logs
- Dependency audit reports
Detection Rules
Splunk Query – Request Payload Inspection
index=web_logs
| search request_body="*__proto__*" OR request_body="*constructor*" OR request_body="*prototype*"
| stats count by client_ip, uri, request_body
Splunk Query – JSON Key Monitoring
index=api_logs
| spath input=request_body
| search request_body="*__proto__*" OR request_body="*constructor*"
| table _time, client_ip, uri, request_body
Elastic / Kibana Query
GET logs-*/_search
{
"query": {
"bool": {
"should": [
{ "match_phrase": { "request_body": "__proto__" }},
{ "match_phrase": { "request_body": "constructor" }},
{ "match_phrase": { "request_body": "prototype" }}
]
}
}
}
ModSecurity WAF Rule
SecRule REQUEST_BODY "(?:__proto__|constructor|prototype)" \
"id:26021,phase:2,deny,log,msg:'Prototype pollution attempt detected'"
Node.js Runtime Monitoring
In controlled environments, monitor:
- Changes to
Object.getOwnPropertyNames(Object.prototype) - Unexpected global property insertions
- Altered behavior of
toString,valueOf, orhasOwnProperty
Such monitoring should be limited to staging due to performance overhead.
How to Confirm Vulnerability Presence
- Run:
npm ls set-in - Check installed version.
- If version < 2.0.5 and >= 2.0.1, the application is vulnerable.
- Inspect dependency tree for transitive inclusion.
Remediation
Immediate upgrade is required.
Upgrade command:
npm install [email protected]
If the dependency is transitive:
- Update parent dependency
- Regenerate lock file
- Rebuild application artifacts
- Redeploy containers or server instances
After upgrade:
- Clear node_modules
- Perform clean install
- Re-run security scan
- Execute regression tests
Temporary Mitigations (If Upgrade Delayed)
- Block dangerous keys at API boundary
- Enforce strict schema validation
- Whitelist allowed object keys
- Reject arrays containing reserved prototype-related strings
- Add WAF inspection rules
- Monitor for suspicious JSON structures
Temporary mitigations must not replace patching.
Patch Information
Upgrade to version 2.0.5 or later.
Official Advisory and Fix:
https://github.com/ahdinosaur/set-in/security/advisories/GHSA-2c4m-g7rx-63q7
Final Takeaway
If set-in processes user-controlled input in a public-facing API, risk should be considered critical.
If only trusted backend logic uses the library without external influence, practical exposure is reduced but patching remains mandatory.
Prototype pollution vulnerabilities frequently become lateral movement facilitators inside applications. Even if immediate RCE is not evident, the structural corruption they introduce can enable chained exploitation.
