CVE-2024-21891 Overview
CVE-2024-21891 is a path traversal vulnerability affecting Node.js that allows attackers to bypass the experimental permission model through the manipulation of built-in utility functions. Node.js relies on multiple built-in utility functions to normalize paths provided to node:fs functions. These utility functions can be overwritten with user-defined implementations, enabling attackers to craft malicious path strings that escape intended directory constraints.
Critical Impact
Attackers with low privileges can bypass filesystem permission restrictions to access, modify, or delete files outside the permitted directories, potentially compromising sensitive data or system integrity.
Affected Products
- Node.js 20.x (with experimental permission model enabled)
- Node.js 21.x (with experimental permission model enabled)
Discovery Timeline
- 2024-02-20 - CVE-2024-21891 published to NVD
- 2025-03-28 - Last updated in NVD database
Technical Details for CVE-2024-21891
Vulnerability Analysis
This vulnerability is classified as CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) and exploits a fundamental design assumption in Node.js's experimental permission model. The permission model was introduced to allow applications to restrict access to specific filesystem paths, providing a sandboxing mechanism for untrusted code.
The core issue lies in how Node.js handles path normalization before enforcing permission checks. The node:fs module depends on built-in utility functions to normalize and resolve paths. However, these utility functions exist in JavaScript space and can be overwritten by user code before the permission checks occur. When an attacker replaces these normalization functions with malicious implementations, they can manipulate the path that gets validated versus the actual path that gets accessed.
This creates a classic time-of-check to time-of-use (TOCTOU) scenario where the permission model validates a safe-looking path, but the actual filesystem operation targets a completely different location through path traversal sequences like ../ that were hidden during validation.
Root Cause
The root cause is insufficient isolation between user-controllable JavaScript code and the internal utility functions used for path normalization in the permission model. The built-in functions that handle path operations can be monkey-patched by application code, and the permission enforcement mechanism does not adequately protect against such modifications.
When the permission model validates a path, it relies on these overwritable functions to normalize the input. An attacker who controls the normalization logic can ensure that validation sees an innocuous path while the actual file operation receives a traversal path targeting protected system files or directories.
Attack Vector
The attack requires network access and low privileges, meaning an attacker needs the ability to execute JavaScript code within the Node.js process. This could be achieved through:
- Exploiting an existing code injection vulnerability in a web application
- Providing malicious npm packages that modify built-in functions
- User-controlled input that gets evaluated as JavaScript
Once the attacker can execute code, they overwrite the path normalization utility functions. When legitimate application code subsequently attempts to access files through the node:fs module, the compromised normalization functions inject path traversal sequences, allowing access to files outside the permitted directories.
The attack is particularly dangerous because the experimental permission model creates a false sense of security—administrators may believe filesystem access is properly constrained when it can actually be bypassed through this mechanism.
Detection Methods for CVE-2024-21891
Indicators of Compromise
- Unexpected modifications to Node.js built-in prototype functions or utility methods
- Filesystem access logs showing access to paths containing ../ sequences or unexpected directory traversal
- Application behavior accessing files outside configured permission boundaries
- Anomalous file read/write operations targeting sensitive system files
Detection Strategies
- Monitor for prototype pollution attempts targeting path-related functions in Node.js applications
- Implement file integrity monitoring on systems running Node.js with the experimental permission model
- Review application logs for path traversal patterns in filesystem operations
- Deploy runtime application self-protection (RASP) solutions that can detect function hooking attempts
Monitoring Recommendations
- Enable verbose logging for node:fs module operations in development and staging environments
- Configure alerts for any filesystem access attempts to sensitive directories like /etc/, /root/, or Windows system directories
- Monitor Node.js process behavior for signs of built-in function modification using security observability tools
- Implement SentinelOne's Singularity platform to detect anomalous process behavior and file access patterns
How to Mitigate CVE-2024-21891
Immediate Actions Required
- Upgrade Node.js to a patched version that addresses CVE-2024-21891
- Audit applications using the experimental permission model for potential exposure
- Review third-party dependencies for any code that modifies built-in utility functions
- Consider disabling the experimental permission model until patches are applied if it is not critical to your application
Patch Information
Security patches addressing this vulnerability are available from the Node.js project. Organizations should upgrade to the latest patched versions of Node.js 20.x and 21.x. Refer to the HackerOne Security Report #2259914 for detailed technical information about the vulnerability disclosure. Additional vendor guidance is available from the NetApp Security Advisory NTAP-20240315-0005 and the Openwall OSS Security Discussion.
Workarounds
- Avoid using the experimental permission model in production environments until the vulnerability is patched
- Implement additional input validation at the application layer before paths reach node:fs functions
- Use containerization or OS-level sandboxing (such as seccomp, AppArmor, or SELinux) as defense-in-depth measures
- Freeze critical built-in objects using Object.freeze() early in application initialization to prevent modification
# Example: Freezing path module early in application startup
# Add to the very beginning of your application entry point
node --require ./freeze-builtins.js your-app.js
# Contents of freeze-builtins.js:
# Object.freeze(require('path'));
# Object.freeze(Object.getPrototypeOf(require('path')));
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


