CVE-2023-23920 - Exploiting The Untrusted Search Path Vulnerability in Node.js ICU Data Handling
In early 2023, a security vulnerability—CVE-2023-23920—was discovered in several versions of Node.js. This issue affects Node.js versions prior to 19.6.1, 18.14.1, 16.19.1, and 14.21.3. The vulnerability centers on an *untrusted search path* that could allow malicious users to inject and load custom ICU data files, possibly leading to code execution, crashes, or information leaks when Node runs with elevated privileges.
In this exclusive long read, we’ll break down the bug, walk through step-by-step exploitation using code snippets, and explore how you can defend your applications. Our goal is to provide a clear, actionable overview for developers and system administrators.
What is ICU Data & Why Does Node.js Need It?
ICU (International Components for Unicode) is a widely used open-source project that provides Unicode and globalization support (like date/time formatting, collation, and locales). Node.js uses ICU functionalities to render text, handle dates, and format strings for different languages.
Normally, Node.js loads the required ICU data in a *secure* and predictable way. But due to the reported untrusted search path vulnerability, there was a way to trick Node.js into looking for ICU data in unsafe, attacker-controlled locations—a classic example of a “search path” bug.
The Vulnerability: How Does It Work?
CVE-2023-23920 arises because, in affected Node.js versions, when a process is started with elevated privileges (like root or administrator), Node.js might search for ICU data in directories that are writable by less privileged users or have not been properly secured.
This untrusted search allows attackers to drop their own specially crafted ICU data file where Node.js will find and use it—causing Node.js to potentially load and interpret attacker-supplied data.
Attack scenario:
The attacker has write access to a directory in the current search path for ICU data AND Node.js is run with higher privileges (e.g., via sudo or as SYSTEM).
Impact:
At best, an attacker could crash Node.js or poison its locale behaviors. At worst, if the file parsing logic is buggy, it can open ways for arbitrary code execution.
1. Find Out Where Node.js Looks for ICU Data
Node.js can be started with the --icu-data-dir flag or set the NODE_ICU_DATA environment variable. If unset, Node.js will search default locations (sometimes including the current directory!)
Example: Set the NODE_ICU_DATA Variable
export NODE_ICU_DATA=.
sudo node vulnerableapp.js
With this variable set, Node.js will search for ICU data files in the current directory. If an attacker can write here, they’re in business.
2. Planting a Malicious ICU Data File
*Creating a truly malicious ICU data file requires in-depth knowledge of ICU file structures, but for demonstration, you can use a copy of a legit file or even a corrupted one.*
# As the attacker (on a shared system):
cp /dev/null ./icudt.dat # An empty (invalid) ICU file
3. Trigger Node.js to Load the Attacker's File
Assuming vulnerableapp.js calls some ICU functionality (like date formatting), running this as root:
sudo NODE_ICU_DATA=. node vulnerableapp.js
If the file is corrupted, Node.js may crash—potentially causing a denial-of-service (DOS).
- If it’s expertly crafted, it might cause logic errors, manipulate output, or worst-of-all, exploit buffer overflows or similar bugs for code execution.
Note: The “real world” exploitability depends on finding a further bug in how Node parses ICU files.
Proof-of-Concept Code
// vulnerableapp.js
// Call ICU-dependent APIs
console.log(new Date().toLocaleString('ru-RU', { timeZone: 'Asia/Tokyo' }));
When NODE_ICU_DATA=. and a malicious icudt.dat is present, you’ve set the stage for exploitation.
Original References
- Node.js Security Release Detail
- ICU Project
- NIST NVD CVE-2023-23920
Closing Thoughts
*CVE-2023-23920* shows how even simple misconfigurations—like an untrusted search path—can open doors for attackers targeting server-side JavaScript. While direct code execution from malicious ICU data is hard, the opportunity for denial-of-service, locale manipulation, or future chaining with parsing bugs makes this issue one to patch ASAP.
Make sure your Node.js installations are up-to-date, use prudent security best practices, and always watch for any signs of tampered internationalization data in your production environments.
Got questions?
Reply below or find more in the Node.js Security Working Group.
Timeline
Published on: 02/23/2023 20:15:00 UTC
Last modified on: 03/16/2023 16:15:00 UTC