GitHub Advisoryadvisory · npm

GHSA-rfx7-4xw3-gh4m @appium/support has a Zip Slip arbitrary file write in its ZIP extraction

MEDIUM Published 2026-03-11 Modified 2026-03-11 Official page ↗
Aliases
CVE-2026-30973
Ecosystem
npm
Packages
@appium/support
Severity
Moderate
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N
Weaknesses
CWE-22
Reviewed
2026-03-11

Affected packages

• npm @appium/support: < 7.0.6 → fixed in 7.0.6

Description

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: ```javascript // 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( // true, () => false)); console.log('outside content:', (await fs.readFile(outside, 'utf8')).trim()); NODE Expected output: outside exists? true outside content: ZIPSLIP_MARKER ``` Impact • Arbitrary file write: An attacker can write files to any location writable by the Appium process, outside the intended extraction directory. • Arbitrary symlink creation: Malicious ZIP entries with symlink attributes can create symlinks pointing to arbitrary targets, enabling further attacks on subsequent file operations. • Potential code execution: By overwriting scripts, configuration files, `node_modules` contents, cron jobs, shell profiles, or other executable artifacts, arbitrary file write can chain into remote code execution. • Affects all JS-based extractions: The default code path (without `useSystemUnzip: true`) is vulnerable regardless of whether `fileNamesEncoding` is set. Recommended Remediation Option 1: Add the missing `throw` keyword (preferred — minimal fix) ```javascript // packages/support/lib/zip.js, line 88 if (relativeDestDir.split(path.sep).includes('..')) { throw new Error( // Add `throw` `Out of bound path "${canonicalDestDir}" found while processing file ${fileName}` ); } ``` This is the lowest-risk fix: it restores the clearly intended behavior of the existing check. The try/catch block at lines 95-99 will catch the error, set `canceled = true`, close the zip, and reject the promise — exactly the designed error-handling flow. Option 2: Add traversal protection to `_extractEntryTo` as well The `_extractEntryTo` function (line 262) also lacks a traversal check. For defense-in-depth, add validation there too: ```javascript async function _extractEntryTo(zipFile, entry, destDir) { const dstPath = path.resolve(destDir, entry.fileName); const canonicalDest = path.resolve(dstPath); const canonicalDestDir = path.resolve(destDir); if (!canonicalDest.startsWith(canonicalDestDir + path.sep) && canonicalDest !== canonicalDestDir) { throw new Error( `Out of bound path "${canonicalDest}" found while processing file ${entry.fileName}` ); } // ... rest of function } ``` Credit This vulnerability was discovered and reported by bugbunny.ai.

Related

Alias · CVE (1)

  • CVE-2026-30973 Appium is an automation framework that provides WebDriver-based automation possibilities for a wide range platforms. vulnerability

Weakness · CWE (1)

  • CWE-22 Improper Limitation of a Pathname to a Restricted Directory weakness

References