Every CVE Search/ Get API key

CVE-2026-30973

Zip Slip arbitrary file write in @appium/support ZIP extraction

6.5 MediumFix available

CVE-2026-30973 is a medium vulnerability (CVSS 6.5) in @appium Support, published March 10, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.44%, the 38th percentile. Fixed in @appium/support 7.0.6.

Appium is an automation framework that provides WebDriver-based automation possibilities for a wide range platforms. Prior to 7.0.6, @appium/support contains a ZIP extraction implementation (extractAllTo() via ZipExtractor.extract()) with a path traversal (Zip Slip) check that is non-functional. The check at line 88 of packages/support/lib/zip.js creates an Error object but never throws it, allowing malicious ZIP entries with ../ path components to write files outside the intended destination directory. This affects all JS-based extractions (the default code path), not only those using the fileNamesEncoding option. This vulnerability is fixed in 7.0.6.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
Required

What an attacker can affect

Confidentiality
None
Integrity
High
Availability
None

Exploit likelihood

0.44%Up 0.4 points since Mar 11, 2026
90%50%10%1%

What each source reports

CVE List Score used 6.5

Zip Slip arbitrary file write in @appium/support ZIP extraction

Appium is an automation framework that provides WebDriver-based automation possibilities for a wide range platforms. Prior to 7.0.6, @appium/support contains a ZIP extraction implementation (extractAllTo() via ZipExtractor.extract()) with a path traversal (Zip Slip) check that is non-functional. The check at line 88 of packages/support/lib/zip.js creates an Error object but never throws it, allowing malicious ZIP entries with ../ path components to write files outside the intended destination directory. This affects all JS-based extractions (the default code path), not only those using the fileNamesEncoding option. This vulnerability is fixed in 7.0.6.

Record
CVE-2026-30973
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N
Weakness
CWE-22
Updated
2026-11-02
EUVDEUVD-2026-10709 6.5

Appium is an automation framework that provides WebDriver-based automation possibilities for a wide range platforms. Prior to 7.0.6, @appium/support contains a ZIP extraction implementation (extractAllTo() via ZipExtractor.extract()) with a path traversal (Zip Slip) check that is non-functional. The check at line 88 of packages/support/lib/zip.js creates an Error object but never throws it, allowing malicious ZIP entries with ../ path components to write files outside the intended destination directory. This affects all JS-based extractions (the default code path), not only those using the fileNamesEncoding option. This vulnerability is fixed in 7.0.6.

Record
EUVD-2026-10709
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-rfx7-4xw3-gh4m 6.5

@appium/support has a Zip Slip arbitrary file write in its ZIP extraction

Summary

@appium/support contains a ZIP extraction implementation (extractAllTo() via ZipExtractor.extract()) with a path traversal (Zip Slip) check that is non-functional. The check at line 88 of packages/support/lib/zip.js creates an Error object but never throws it, allowing malicious ZIP entries with ../ path components to write files outside the intended destination directory. This affects all JS-based extractions (the default code path), not only those using the fileNamesEncoding option.

Severity

Medium (CVSS 3.1: 6.5)

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N

  • Attack Vector: Network — malicious ZIP files can be supplied over the network (e.g., app packages via URL)
  • Attack Complexity: Low — no special conditions required beyond providing a crafted ZIP
  • Privileges Required: None — no authentication needed to supply a malicious archive
  • User Interaction: Required — a user or automation system must initiate extraction of the attacker's archive
  • Scope: Unchanged — impact stays within the file system permissions of the Appium process
  • Confidentiality Impact: None — the vulnerability enables file writes, not reads
  • Integrity Impact: High — arbitrary file write to any location writable by the process
  • Availability Impact: None — no direct availability impact

Affected Component

  • packages/support/lib/zip.js — ZipExtractor.extract() (line 88) and ZipExtractor.extractEntry() (lines 111-145)

CWE

  • CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Description

Missing throw renders Zip Slip protection non-functional

The ZipExtractor.extract() method contains a path traversal check intended to prevent Zip Slip attacks. However, the check creates an Error object as a bare expression without the throw keyword, making it a no-op:

// packages/support/lib/zip.js, lines 80-93
const destDir = path.dirname(path.join(dir, fileName));
try {
    await fs.mkdir(destDir, {recursive: true});

    const canonicalDestDir = await fs.realpath(destDir);
    const relativeDestDir = path.relative(dir, canonicalDestDir);

    if (relativeDestDir.split(path.sep).includes('..')) {
        new Error(                                          // <-- BUG: missing `throw`
            `Out of bound path "${canonicalDestDir}" found while processing file ${fileName}`
        );
    }

    await this.extractEntry(entry);   // extraction proceeds unconditionally

The presence of a well-formatted error message and surrounding try/catch block (lines 95-99) strongly suggests the throw keyword was accidentally omitted.

yauzl does not provide its own traversal protection

The upstream yauzl library explicitly does not offer path traversal protection regardless of the decodeStrings setting. This means the vulnerability affects all JS-based extractions through ZipExtractor, not only those where fileNamesEncoding is set. The fileNamesEncoding option bypasses yauzl's string decoding (decodeStrings: false), but even with decodeStrings: true, yauzl passes through ../ path components without rejection.

Unprotected write sinks

The extractEntry method writes to attacker-controlled paths with no additional validation:

// packages/support/lib/zip.js, lines 111-145
const fileName = this.extractFileName(entry);
const dest = path.join(dir, fileName);         // resolves ../pwned.txt outside dir
// ...
await fs.symlink(link, dest);                  // symlink creation (line 143)
await pipeline(readStream, fs.createWriteStream(dest, {mode: procMode}));  // file write (line 145)

Additionally, _extractEntryTo() (line 263) used by readEntries() has no traversal check at all:

const dstPath = path.resolve(destDir, entry.fileName);  // no validation

Default…

Record
GHSA-rfx7-4xw3-gh4m
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N
Weakness
CWE-22
Updated
2026-11-02
NVD 6.5

Appium is an automation framework that provides WebDriver-based automation possibilities for a wide range platforms. Prior to 7.0.6, @appium/support contains a ZIP extraction implementation (extractAllTo() via ZipExtractor.extract()) with a path traversal (Zip Slip) check that is non-functional. The check at line 88 of packages/support/lib/zip.js creates an Error object but never throws it, allowing malicious ZIP entries with ../ path components to write files outside the intended destination directory. This affects all JS-based extractions (the default code path), not only those using the fileNamesEncoding option. This vulnerability is fixed in 7.0.6.

Record
CVE-2026-30973
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N
Weakness
CWE-22
Updated
2026-11-02
OSV 6.5

Zip Slip arbitrary file write in @appium/support ZIP extraction

Appium is an automation framework that provides WebDriver-based automation possibilities for a wide range platforms. Prior to 7.0.6, @appium/support contains a ZIP extraction implementation (extractAllTo() via ZipExtractor.extract()) with a path traversal (Zip Slip) check that is non-functional. The check at line 88 of packages/support/lib/zip.js creates an Error object but never throws it, allowing malicious ZIP entries with ../ path components to write files outside the intended destination directory. This affects all JS-based extractions (the default code path), not only those using the fileNamesEncoding option. This vulnerability is fixed in 7.0.6.

Record
CVE-2026-30973
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N
Weakness
CWE-22
Updated
2026-11-02
OSVGHSA-rfx7-4xw3-gh4m 6.5

@appium/support has a Zip Slip arbitrary file write in its ZIP extraction

Summary

@appium/support contains a ZIP extraction implementation (extractAllTo() via ZipExtractor.extract()) with a path traversal (Zip Slip) check that is non-functional. The check at line 88 of packages/support/lib/zip.js creates an Error object but never throws it, allowing malicious ZIP entries with ../ path components to write files outside the intended destination directory. This affects all JS-based extractions (the default code path), not only those using the fileNamesEncoding option.

Severity

Medium (CVSS 3.1: 6.5)

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N

  • Attack Vector: Network — malicious ZIP files can be supplied over the network (e.g., app packages via URL)
  • Attack Complexity: Low — no special conditions required beyond providing a crafted ZIP
  • Privileges Required: None — no authentication needed to supply a malicious archive
  • User Interaction: Required — a user or automation system must initiate extraction of the attacker's archive
  • Scope: Unchanged — impact stays within the file system permissions of the Appium process
  • Confidentiality Impact: None — the vulnerability enables file writes, not reads
  • Integrity Impact: High — arbitrary file write to any location writable by the process
  • Availability Impact: None — no direct availability impact

Affected Component

  • packages/support/lib/zip.js — ZipExtractor.extract() (line 88) and ZipExtractor.extractEntry() (lines 111-145)

CWE

  • CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Description

Missing throw renders Zip Slip protection non-functional

The ZipExtractor.extract() method contains a path traversal check intended to prevent Zip Slip attacks. However, the check creates an Error object as a bare expression without the throw keyword, making it a no-op:

// packages/support/lib/zip.js, lines 80-93
const destDir = path.dirname(path.join(dir, fileName));
try {
    await fs.mkdir(destDir, {recursive: true});

    const canonicalDestDir = await fs.realpath(destDir);
    const relativeDestDir = path.relative(dir, canonicalDestDir);

    if (relativeDestDir.split(path.sep).includes('..')) {
        new Error(                                          // <-- BUG: missing `throw`
            `Out of bound path "${canonicalDestDir}" found while processing file ${fileName}`
        );
    }

    await this.extractEntry(entry);   // extraction proceeds unconditionally

The presence of a well-formatted error message and surrounding try/catch block (lines 95-99) strongly suggests the throw keyword was accidentally omitted.

yauzl does not provide its own traversal protection

The upstream yauzl library explicitly does not offer path traversal protection regardless of the decodeStrings setting. This means the vulnerability affects all JS-based extractions through ZipExtractor, not only those where fileNamesEncoding is set. The fileNamesEncoding option bypasses yauzl's string decoding (decodeStrings: false), but even with decodeStrings: true, yauzl passes through ../ path components without rejection.

Unprotected write sinks

The extractEntry method writes to attacker-controlled paths with no additional validation:

// packages/support/lib/zip.js, lines 111-145
const fileName = this.extractFileName(entry);
const dest = path.join(dir, fileName);         // resolves ../pwned.txt outside dir
// ...
await fs.symlink(link, dest);                  // symlink creation (line 143)
await pipeline(readStream, fs.createWriteStream(dest, {mode: procMode}));  // file write (line 145)

Additionally, _extractEntryTo() (line 263) used by readEntries() has no traversal check at all:

const dstPath = path.resolve(destDir, entry.fileName);  // no validation

Default…

Record
GHSA-rfx7-4xw3-gh4m
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N
Weakness
CWE-22
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
@appium/support
npm
through 7.0.5
7.0.6
@appium/support
npm
before 7.0.6
7.0.6

History

History
WhenChangedSources
2026-11-02createdCVE List, EUVD, GitHub Advisories, NVD, OSV

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open