| Package Name | Ecosystem | Vulnerable Versions | First Patched Version |
|---|---|---|---|
| tar | npm | = 7.5.1 | 7.5.2 |
The analysis of the provided patches pinpoints the vulnerability to the listFileSync function in src/list.ts. The vulnerability is a classic TOCTOU (time-of-check to time-of-use) race condition. The vulnerability description explicitly mentions that the regression happened in commit 5330eb04bc43014f216e5c271b40d5c00d45224d. This commit modified listFileSync to first check the file size (stat.size), then allocate an unsafe buffer of that size, and finally read the file. This creates a window for an attacker to truncate the file. If the file is made smaller during this window, fs.readSync reads fewer bytes than the buffer size, but the entire buffer, including the uninitialized parts, is passed to the parser. The fixing commit, 5e1a8e638600d3c3a2969b4de6a6ec44fa8d74c9, addresses this by checking the number of bytes actually read and slicing the buffer to that size before passing it to the parser, thus preventing the leakage of uninitialized memory. The vulnerable function is internal and called when a user invokes tar.list() or tar.t() with the { sync: true } option.
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.