CVE-2024-21896
High · 7.9CVSS
7.9
EPSS
1.3%
Published
Feb 20, 2024
CISA due date
—
Cloudanix analysis
A flaw in an experimental security feature of Node.js could let attackers reach files they should not be allowed to access by tricking the system's path checks.
- Exploitation
- Requires User Interaction
- Attacker needs
- Local User
- Complexity
- Moderate
- Impact
- Full Compromise
- Component
- Application
- Class
- Path Traversal
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
Monkey-patching Buffer.prototype.utf8Write allows an attacker to alter the result of path.resolve() when the permission model converts resolved paths to Buffers, bypassing path traversal protections in the experimental permission model.
Why it matters to the business
Applications relying on Node.js experimental permissions may inadvertently grant access to files outside intended directories, risking data exposure or unauthorized operations in sandboxed environments; low adoption due to experimental status reduces widespread impact but still requires prompt attention for users testing the feature.
How an attack unfolds
An attacker first monkey-patches Buffer.prototype.utf8Write in the target Node.js process using the experimental permission model, then supplies a user-controlled path intended for Buffer conversion; the patched method modifies the resolved path at runtime to traverse outside allowed directories, evading the permission checks.
How to fix it
Update Node.js to a build containing commit 3eccdd1ae61777a381a7ac3bc0ea62443dbb50b8 or later; disable the experimental permission model via --experimental-permission if the feature is not required.
How to confirm the fix worked
Verify Node.js binary or source includes the referenced commit; attempt path traversal inputs under the permission model both before and after the update to confirm enforcement; review application startup flags for permission model usage.
Typical attack path
- Identify Node.js application using experimental permission model in versions 20 or 21
- Inject code to monkey-patch Buffer.prototype.utf8Write before permission checks run
- Provide crafted path input that path.resolve() processes
- Trigger Buffer.from() conversion on the resolved path to activate the patch
- Access or manipulate files outside the permitted directory tree
How to detect it
Review application source and runtime for dynamic modifications to Buffer.prototype.utf8Write; inspect Node.js process startup arguments and permission model configuration; examine file access logs for unexpected paths when the permission model is active.
What your security team should do
- Audit all Node.js deployments for use of the experimental permission model
- Apply the fix commit immediately on affected 20.x and 21.x branches
- Disable --experimental-permission in production until the model stabilizes
- Monitor upstream Node.js releases for permission model updates
The record
The permission model protects itself against path traversal attacks by calling path.resolve() on any paths given by the user. If the path is to be treated as a Buffer, the implementation uses Buffer.from() to obtain a Buffer from the result of path.resolve(). By monkey-patching Buffer internals, namely, Buffer.prototype.utf8Write, the application can modify the result of path.resolve(), which leads to a path traversal vulnerability. This vulnerability affects all users using the experimental permission model in Node.js 20 and Node.js 21. Please note that at the time this CVE was issued, the permission model is an experimental feature of Node.js.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| AlmaLinux:8 | nodejs | 0 | 1:20.11.1-1.module_el8.9.0+3775+d8460d35 |
| AlmaLinux:8 | nodejs-devel | 0 | 1:20.11.1-1.module_el8.9.0+3775+d8460d35 |
| AlmaLinux:8 | nodejs-docs | 0 | 1:20.11.1-1.module_el8.9.0+3775+d8460d35 |
| AlmaLinux:8 | nodejs-full-i18n | 0 | 1:20.11.1-1.module_el8.9.0+3775+d8460d35 |
| AlmaLinux:8 | nodejs-nodemon | 0 | 3.0.1-1.module_el8.9.0+3731+490e3ce5 |
| AlmaLinux:8 | nodejs-packaging | 0 | 2021.06-4.module_el8.9.0+3684+11b9e959 |
| AlmaLinux:8 | nodejs-packaging-bundler | 0 | 2021.06-4.module_el8.9.0+3684+11b9e959 |
| AlmaLinux:8 | npm | 0 | 1:10.2.4-1.20.11.1.1.module_el8.9.0+3775+d8460d35 |
| AlmaLinux:9 | nodejs | 0 | 1:20.11.1-1.module_el9.3.0+88+29afeaa2 |
| AlmaLinux:9 | nodejs-devel | 0 | 1:20.11.1-1.module_el9.3.0+88+29afeaa2 |
| AlmaLinux:9 | nodejs-docs | 0 | 1:20.11.1-1.module_el9.3.0+88+29afeaa2 |
| AlmaLinux:9 | nodejs-full-i18n | 0 | 1:20.11.1-1.module_el9.3.0+88+29afeaa2 |
| AlmaLinux:9 | nodejs-nodemon | 0 | 3.0.1-1.module_el9.3.0+47+c33bc288 |
| AlmaLinux:9 | nodejs-packaging | 0 | 2021.06-4.module_el9.3.0+48+1cf146a1 |
| AlmaLinux:9 | nodejs-packaging-bundler | 0 | 2021.06-4.module_el9.3.0+48+1cf146a1 |
| AlmaLinux:9 | npm | 0 | 1:10.2.4-1.20.11.1.1.module_el9.3.0+88+29afeaa2 |
| Bitnami | node | 20.0.0 | 20.12.0 |
| Bitnami | node | 21.0.0 | 21.6.2 |
| Bitnami | node-min | 20.0.0 | 20.18.1 |
| Bitnami | node-min | 21.0.0 | 21.6.2 |
| Red Hat:enterprise_linux:8::appstream | nodejs | 0 | 1:20.11.1-1.module+el8.9.0+21380+12032667 |
| Red Hat:enterprise_linux:8::appstream | nodejs-debuginfo | 0 | 1:20.11.1-1.module+el8.9.0+21380+12032667 |
| Red Hat:enterprise_linux:8::appstream | nodejs-debugsource | 0 | 1:20.11.1-1.module+el8.9.0+21380+12032667 |
| Red Hat:enterprise_linux:8::appstream | nodejs-devel | 0 | 1:20.11.1-1.module+el8.9.0+21380+12032667 |
| Red Hat:enterprise_linux:8::appstream | nodejs-docs | 0 | 1:20.11.1-1.module+el8.9.0+21380+12032667 |
| Red Hat:enterprise_linux:8::appstream | nodejs-full-i18n | 0 | 1:20.11.1-1.module+el8.9.0+21380+12032667 |
| Red Hat:enterprise_linux:8::appstream | nodejs-nodemon | 0 | 0:3.0.1-1.module+el8.9.0+20473+c4e3d824 |
| Red Hat:enterprise_linux:8::appstream | nodejs-packaging | 0 | 0:2021.06-4.module+el8.9.0+19519+e25b965a |
| Red Hat:enterprise_linux:8::appstream | nodejs-packaging-bundler | 0 | 0:2021.06-4.module+el8.9.0+19519+e25b965a |
| Red Hat:enterprise_linux:8::appstream | npm | 0 | 1:10.2.4-1.20.11.1.1.module+el8.9.0+21380+12032667 |
| Red Hat:enterprise_linux:9::appstream | nodejs | 0 | 1:20.11.1-1.module+el9.3.0+21385+bac43d5a |
| Red Hat:enterprise_linux:9::appstream | nodejs-debuginfo | 0 | 1:20.11.1-1.module+el9.3.0+21385+bac43d5a |
| Red Hat:enterprise_linux:9::appstream | nodejs-debugsource | 0 | 1:20.11.1-1.module+el9.3.0+21385+bac43d5a |
| Red Hat:enterprise_linux:9::appstream | nodejs-devel | 0 | 1:20.11.1-1.module+el9.3.0+21385+bac43d5a |
| Red Hat:enterprise_linux:9::appstream | nodejs-docs | 0 | 1:20.11.1-1.module+el9.3.0+21385+bac43d5a |
| Red Hat:enterprise_linux:9::appstream | nodejs-full-i18n | 0 | 1:20.11.1-1.module+el9.3.0+21385+bac43d5a |
| Red Hat:enterprise_linux:9::appstream | nodejs-nodemon | 0 | 0:3.0.1-1.module+el9.3.0.z+20478+84a9f781 |
| Red Hat:enterprise_linux:9::appstream | nodejs-packaging | 0 | 0:2021.06-4.module+el9.3.0+19518+63aad52d |
| Red Hat:enterprise_linux:9::appstream | nodejs-packaging-bundler | 0 | 0:2021.06-4.module+el9.3.0+19518+63aad52d |
| Red Hat:enterprise_linux:9::appstream | npm | 0 | 1:10.2.4-1.20.11.1.1.module+el9.3.0+21385+bac43d5a |
| Rocky Linux:8 | nodejs | 0 | 1:20.11.1-1.module+el8.9.0+1776+addd4aec |
| Rocky Linux:8 | nodejs-nodemon | 0 | 0:3.0.1-1.module+el8.8.0+1459+02651ab6 |
| Rocky Linux:8 | nodejs-packaging | 0 | 0:2021.06-4.module+el8.7.0+1072+5b168780 |
| Rocky Linux:9 | nodejs-nodemon | 0 | 0:3.0.1-1.module+el9.2.0+15226+de336927 |
| Rocky Linux:9 | nodejs-nodemon | 0 | 0:3.0.1-1.module+el9.6.0+32322+a8b1fd01 |
| Rocky Linux:9 | nodejs-packaging | 0 | 0:2021.06-4.module+el9.2.0+15226+de336927 |
| Rocky Linux:9 | nodejs-packaging | 0 | 0:2021.06-4.module+el9.5.0+31770+0da7192d |
| SUSE:Linux Enterprise Module for Web and Scripting 15 SP5 | nodejs20 | 0 | 20.11.1-150500.11.6.1 |
| Ubuntu:20.04:LTS | nodejs | 0 | No fix |
| Ubuntu:22.04:LTS | nodejs | 0 | No fix |
| Ubuntu:24.04:LTS | nodejs | 0 | No fix |
| Ubuntu:24.10 | nodejs | 0 | No fix |
| Ubuntu:25.04 | nodejs | 0 | No fix |
| Ubuntu:25.10 | nodejs | 0 | No fix |
| Ubuntu:Pro:14.04:LTS | nodejs | 0 | No fix |
| Ubuntu:Pro:16.04:LTS | nodejs | 0 | No fix |
| Ubuntu:Pro:18.04:LTS | nodejs | 0 | No fix |
| openSUSE:Leap 15.5 | nodejs20 | 0 | 20.11.1-150500.11.6.1 |
| openSUSE:Tumbleweed | nodejs20 | 0 | 20.11.1-1.1 |
| openSUSE:Tumbleweed | nodejs21 | 0 | 21.6.2-1.1 |
Related vulnerabilities
- CVE-2025-6965 There exists a vulnerability in SQLite versions before 3.50.2 where the number of… Also affects nodejs
- CVE-2025-23085 A memory leak could occur when a remote peer abruptly closes the socket without sending a… Also affects nodejs
- CVE-2025-23083 With the aid of the diagnostics_channel utility, an event can be hooked into whenever a… Also affects nodejs
- CVE-2025-22150 Undici is an HTTP/1.1 client. Also affects nodejs
- CVE-2023-39333 Maliciously crafted export names in an imported WebAssembly module can inject JavaScript… Also affects nodejs
- CVE-2023-46809 Node.js versions which bundle an unpatched version of OpenSSL or run against a… Also affects nodejs
- CVE-2024-36137 A vulnerability has been identified in Node.js, affecting users of the experimental… Also affects nodejs
- CVE-2024-22018 A vulnerability has been identified in Node.js, affecting users of the experimental… Also affects nodejs