| Package Name | Ecosystem | Vulnerable Versions | First Patched Version |
|---|---|---|---|
| tar | npm | = 7.5.1 | 7.5.2 |
The vulnerability exists in the synchronous file listing functionality of the node-tar library, specifically within the listFileSync function located in src/list.ts. The vulnerability was introduced in commit 5330eb04bc43014f216e5c271b40d5c00d45224d, which changed the file reading logic. The new logic introduced a time-of-check-to-time-of-use (TOCTOU) race condition. It checks the file size, allocates an uninitialized buffer of that size (Buffer.allocUnsafe), and then reads the file. If the file is made smaller by an external process during this window, the read operation will not fill the entire buffer, causing the uninitialized (and potentially sensitive) memory to be passed to the tar parser. The fix, applied in commit 5e1a8e638600d3c3a2969b4de6a6ec44fa8d74c9, resolves this by using the return value of fs.readSync to determine how many bytes were actually read and then passing only that portion of the buffer to the parser. The user-facing API for this functionality is tar.list({ sync: true }) or tar.t({ sync: true }), which would call the vulnerable listFileSync function internally.
listFileSyncsrc/list.ts
To execute, an attacker must reduce the file size to boundary between a tar header and body block, in the time between when the tar archive file size is read via stat, and the time when the tar archive parser reaches the entry that is truncated. If the file is truncated at a different boundary, then the uninitialized data will very likely not be a valid tar entry, causing the parser to treat the entry as a damaged archive (that is, throwing an error in strict: true mode, or by default, skipping the entry harmlessly).
This is conditional on using the sync: true option to the tar.list/tar.t method, and the 7.5.1 version specifically. Earlier versions were not affected.
This is also conditional to attacker being able to truncate (or induce a truncation/replacement) of a file on disk (e.g. in cache).
If the tar file is initially larger than the opt.maxReadSize (16kb by default), then uninitialized memory is not exposed to user code, and instead the program enters an infinite loop, causing a DoS rather than an information disclosure vulnerability.
By default, tar.list does not process tar archive entry body content. So, this is further conditional on the user code doing something with the tar entry file contents in an onReadEntry method which would expose the file contents (for example, attempting to parse them in such a way that the uninitialized data could appear in an error message).
Other methods in this library (tar.extract, etc.) are not affected by this vulnerability.
Ongoing coverage of React2Shell