GitHub Advisoryadvisory · npm
GHSA-rfx7-4xw3-gh4m @appium/support has a Zip Slip arbitrary file write in its ZIP extraction
MEDIUM
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