When unpacking a tar archive, the tar crate's unpack_dir function uses fs::metadata() to check whether a path that already exists is a directory. Because fs::metadata() follows symbolic links, a crafted tarball containing a symlink entry followed by a directory entry with the same name causes the crate to treat the symlink target as a valid existing directory — and subsequently apply chmod to it. This allows an attacker to modify the permissions of arbitrary directories outside the extraction root.
A malicious tarball contains two entries: (1) a symlink foo pointing to an arbitrary external directory, and (2) a directory entry foo/. (or just foo). When unpacked, create_dir("foo") fails with EEXIST because the symlink is already on disk. The fs::metadata() check then follows the symlink, sees a directory at the target, and allows processing to continue. The directory entry's mode bits are then applied via chmod, which also follows the symlink — modifying the permissions of the external target directory.
The fix is very simple, we now use fs::symlink_metadata() in unpack_dir, so symlinks are detected and rejected rather than followed.
This issue was reported by @xokdvium - thank you!
| Score | Percentile |
|---|---|
| 0.01% | 1.44% |
| Base score | Version | Severity | Vector |
|---|---|---|---|
| 6.5 | 3.1 | — |
|
| 5.1 | 4.0 | — |
|
| Type | Value |
|---|---|
| GHSA | GHSA-j4xf-2g29-59ph ↗ |
| CVE | CVE-2026-33056 ↗ |
| CWE id | Name |
|---|---|
| CWE-61 | UNIX Symbolic Link (Symlink) Following |
Vulnerable version ranges and first patched releases as published by GitHub.
| Ecosystem | Package | Vulnerable range | First patched | Vulnerable functions |
|---|---|---|---|---|
| rust | tar | <= 0.4.44 | 0.4.45 | — |