GHSA-gv7w-rqvm-qjhr Withdrawn Advisory: esbuild: Missing binary integrity verification in Deno module enables remote code execution via NPM_CONFIG_REGISTRY
Withdrawn AdvisoryThis advisory has been withdrawn because the affected package was incorrectly identified and the [actual affected package](https://github.com/esbuild/deno-esbuild) is not in a supported ecosystem. This link is maintained to preserve external references.Original DescriptionSummaryThe esbuild Deno module (`lib/deno/mod.ts`) downloads native binary executables from an npm registry and writes them to disk with executable permissions (`0o755`) **without performing any integrity verification** (e.g., SHA-256 hash check). The Node.js equivalent (`lib/npm/node-install.ts`) includes a robust `binaryIntegrityCheck()` function that verifies SHA-256 hashes against hardcoded expected values from `package.json`, but this protection was never implemented for the Deno distribution.When the `NPM_CONFIG_REGISTRY` environment variable is set, the Deno module constructs a download URL using this attacker-influenced value and fetches a native binary from it. Because no integrity check is performed, an attacker who can control this environment variable (common in CI/CD pipelines, shared development environments, or corporate networks with custom npm registries) can supply a malicious binary that will be downloaded, written to disk, and executed with the privileges of the Deno process, achieving full remote code execution.Details**Vulnerable code path** — `lib/deno/mod.ts` lines 62–82:**Missing protection** — The Node.js equivalent at `lib/npm/node-install.ts` lines 228–234:This function is called in both the `installUsingNPM()` path (line 131) and the `downloadDirectlyFromNPM()` path (line 243), but **no equivalent exists in the Deno module**. Searching the entire git history confirms `binaryIntegrityCheck`, `binaryHashes`, `sha256`, and `hash` have never appeared in `lib/deno/mod.ts`.**Execution flow after download:** The binary returned by `installFromNPM()` is passed to `spawn()` at line 291 of the same file:**Attack vector:** The `NPM_CONFIG_REGISTRY` environment variable is a standard npm configuration variable widely used in enterprise CI/CD pipelines to point to internal artifact repositories (Artifactory, Nexus, Verdaccio, etc.). An attacker who can inject or modify this variable in a build environment (e.g., via CI config injection, shared environment, or compromised registry) can redirect the download to a server they control and serve a trojaned native binary.PoC**Prerequisites:** Deno runtime, Node.js (for fake registry)**Step 1:** Create a fake npm registry that serves a malicious binary:**Step 2:** Run the PoC with `NPM_CONFIG_REGISTRY` pointing to the fake server:**Step 3:** Run:**Observed output in this environment:****Build-local verification — using the actual built `deno/mod.js`:**The esbuild Deno module was built from source (`node scripts/esbuild.js ./esbuild --deno`) producing `deno/mod.js`. The fake registry test was then re-run using the **actual module** via `import * as esbuild from "file:///path/to/deno/mod.js"`, triggering the real `installFromNPM()` → `installFromNPM()` code path:The malicious binary was cached at `~/.cache/esbuild/bin/@esbuild-linux-x64@0.28.0` with contents:Built-in Deno module (`deno/mod.js`) confirmed to contain `NPM_CONFIG_REGISTRY` usage (line 1900) and zero references to `binaryIntegrityCheck`, `binaryHashes`, `sha256`, or `crypto.createHash`.**Negative/control case — Node.js rejects the same fake binary:**ImpactAn attacker who can control the `NPM_CONFIG_REGISTRY` environment variable in a Deno project using esbuild can achieve **arbitrary code execution** with the privileges of the Deno process. This is particularly relevant in:**CI/CD pipelines** where `NPM_CONFIG_REGISTRY` is commonly set to point to internal artifact repositories**Shared development environments** where environment variables may be inherited from parent processes**Corporate networks** where npm registry mirrors are configured via this environment variableThe attacker does not need to compromise the npm registry itself — only the environment variable or network path between the Deno process and the registry.Suggested remediation**Add SHA-256 integrity verification to the Deno module**, mirroring the existing `binaryIntegrityCheck()` function from `lib/npm/node-install.ts`:**Validate the `NPM_CONFIG_REGISTRY` URL** to ensure it uses HTTPS (or at minimum warn about HTTP):**Add `ESBUILD_BINARY_PATH` validation** in the Deno module, mirroring the `isValidBinaryPath()` check from `lib/npm/node-platform.ts`.**Regression test suggestion:** Add a test that verifies the Deno download path rejects a binary with a mismatched SHA-256 hash.
CVSS v3.1 score: 8.1