Jun 15, 2026·6 min read·8 visits
Missing binary integrity verification in esbuild's Deno installer allows unauthenticated remote code execution via a poisoned registry configuration.
An issue was discovered in the Deno integration of the esbuild package. The module fails to verify the integrity of downloaded native binary packages from NPM registries before writing and executing them on the local filesystem. This allows an attacker who controls the NPM_CONFIG_REGISTRY environment variable or intercepts the network connection to execute arbitrary native code on the host machine.
The Deno integration module of the esbuild package downloader exposes an unauthenticated remote code execution vulnerability. When running in a Deno environment, esbuild retrieves platform-specific native binaries from an NPM registry. The vulnerability arises because the installer fails to perform cryptographic signature or integrity verification on the downloaded tarball before writing the binary to the local system and executing it.
An attacker can trigger this vulnerability by manipulating environment variables such as NPM_CONFIG_REGISTRY to point to a malicious server, or by executing a man-in-the-middle attack on the network path. Because Deno applications frequently execute within high-privilege pipelines or developer environments, this lack of validation presents a substantial initial access and execution hijacking vector.
The weakness is classified under CWE-494 (Download of Code Without Integrity Check) and CWE-426 (Untrusted Search Path). It impacts all versions of esbuild starting from 0.17.0 up to, but excluding, version 0.28.1.
The root cause of this security flaw lies in the discrepancy between how the Node.js installer and the Deno installer wrapper verify binary payloads. The Node.js implementation enforces checksum integrity checks using a hardcoded JSON manifest containing SHA-256 hashes for each architecture. In contrast, the Deno installer implemented in lib/deno/mod.ts completely lacks any integrity checks or validation routines.
When a Deno application initializes esbuild, the module executes the installFromNPM helper function to check if the platform-specific native binary is available locally. If the binary is missing, the code queries the environment for the NPM_CONFIG_REGISTRY variable to determine the base download URL. If this variable is defined, the installer uses it to build the request path; otherwise, it defaults to the official npmjs registry.
Once the URL is constructed, the module issues an HTTP request using Deno's global fetch API. It reads the response body as an ArrayBuffer and immediately extracts the target executable using a custom tar-gzip extractor. No validation is conducted against the binary content or the archive structure before writing the executable to disk with read-write-execute permissions (0o755).
To understand the exact breakdown, we examine the vulnerable code path located in lib/deno/mod.ts within the affected version range. The implementation constructs the endpoint and fetches the binary archive using the following sequence:
// Affected Code: lib/deno/mod.ts
async function installFromNPM(name: string, subpath: string): Promise<string> {
const { finalPath, finalDir } = getCachePath(name);
try { await Deno.stat(finalPath); return finalPath } catch (e) {}
// The URL construction relies directly on the environment variable
const npmRegistry = Deno.env.get("NPM_CONFIG_REGISTRY") || "https://registry.npmjs.org";
const url = `${npmRegistry}/${name}/-/${name.replace("@esbuild/", "")}-${version}.tgz`;
// Unchecked remote download occurs here
const buffer = await fetch(url).then(r => r.arrayBuffer());
const executable = extractFileFromTarGzip(new Uint8Array(buffer), subpath);
// Writing the extracted binary with executable permissions
await Deno.mkdir(finalDir, { recursive: true, mode: 0o700 });
await Deno.writeFile(finalPath, executable, { mode: 0o755 });
return finalPath;
}In contrast, the Node.js implementation in lib/npm/node-install.ts enforces validation of the payload bytes using a built-in cryptographic hashing function. This ensures that even if a registry mirror is compromised or spoofed, the target environment refuses to write or execute anomalous binaries:
// Node.js Implementation: lib/npm/node-install.ts
function binaryIntegrityCheck(pkg: string, subpath: string, bytes: Uint8Array): void {
const hash = crypto.createHash('sha256').update(bytes).digest('hex');
const key = `${pkg}/${subpath}`;
const expected = packageJSON['esbuild.binaryHashes'][key];
if (!expected) throw new Error(`Missing hash for "${key}"`);
if (hash !== expected) throw new Error(`Hash mismatch for "${key}"`);
}The fix introduced in version 0.28.1 ports this cryptographic checksum verification to the Deno implementation. It resolves the vulnerability by mapping the downloaded bytes against the same static manifest hashes before the local filesystem write occurs. This ensures parity in security postures across both Node.js and Deno execution environments.
The exploitation of GHSA-GV7W-RQVM-QJHR relies on hijacking the source location of the downloaded package. In an enterprise or automated environment, an attacker can poison the NPM_CONFIG_REGISTRY environment variable to point to a malicious server. Alternatively, in a shared host or developer environment, the attacker can leverage local environment mutation permissions to force this redirection.
The attacker prepares a mock registry that returns a crafted gzip tarball containing a malicious script or binary disguised as the native executable. When installFromNPM is triggered, it requests the package from the malicious endpoint. The victim's application downloads and decompresses the payload, subsequently executing it with the active user permissions.
Below is a flow diagram illustrating the hijack sequence from environment poisoning to remote code execution:
This architecture guarantees that any environment in which Deno runs without strict permissions is susceptible to complete compromise. If Deno is launched with broad system permissions, the executed script can capture secrets, perform network reconnaissance, or establish persistence.
The security impact of this vulnerability is high, carrying a CVSS v3.1 score of 8.1. The attack vector is network-based, but exploitation requires specific conditions relating to environment manipulation or local access, which bounds the complexity. However, successful exploitation yields unauthenticated arbitrary code execution under the context of the running Deno process.
In automated environments such as continuous integration (CI) pipelines or automated deployment servers, Deno commands are often run with high privileges. A compromise in these contexts can lead to supply chain taint, exfiltration of sensitive environment variables, or unauthorized infrastructure control. Because the vulnerability involves the execution of native code, it evades standard Deno runtime limits if those flags are configured loosely.
As of current intelligence, this vulnerability is not listed on CISA's Known Exploited Vulnerabilities (KEV) catalog, nor is there active ransomware usage reported. However, due to the ease of constructing a proof-of-concept, development teams should prioritize remediation.
The primary and recommended mitigation is upgrading esbuild to version 0.28.1 or higher. This update introduces mandatory cryptographic verification using a static mapping of binary hashes. If upgrading is not immediately possible, security teams should implement restrictive runtime configurations to isolate the vulnerability.
Developers should avoid using the --allow-all or -A flags when executing untrusted or unverified Deno applications. Specifically, omitting or constraining the --allow-run permission blocks the Deno process from spawning the downloaded executable, neutralizing the remote code execution vector. Similarly, restricting the --allow-env permission prevents the application from reading a poisoned NPM_CONFIG_REGISTRY variable.
Additionally, implementing strict network egress controls ensures that Deno installers can only communicate with trusted, verified artifact repositories. Internal build environments should use read-only configurations for system-wide environment variables to prevent unauthorized modifications to registry pathways.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
esbuild (Deno module) evanw | >= 0.17.0, < 0.28.1 | 0.28.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-494, CWE-426 |
| Attack Vector | Network / Local Environment Manipulation |
| CVSS Score | 8.1 (High) |
| Exploit Status | Proof of Concept (PoC) available |
| CISA KEV Status | Not Listed |
| Impact | Remote Code Execution (RCE) |
The application downloads source code or executable binaries from a remote source but does not verify that the code's integrity matches an expected cryptographic hash.
An authenticated backend user with access to the Recycler module in TYPO3 CMS can bypass write restrictions and restore soft-deleted records on pages or database tables they are not authorized to modify. This vulnerability resides in the core DataHandler class due to missing permission checks during 'undelete' operations.
CVE-2026-11607 is a critical broken access control vulnerability in TYPO3 CMS's Form Framework (ext:form). Authenticated backend users with access to the Form Framework can load unauthorized YAML configurations, bypassing file extension restrictions. This allows the execution of arbitrary SQL commands via the SaveToDatabase finisher, leading to privilege escalation to administrator level.
Improper validation of backslash character separators in esbuild's local development server allows path traversal on Windows systems.
A thread-safety vulnerability exists in the PyO3 library versions prior to 0.29.0 due to a missing Sync trait bound on closure type parameters. This omission allows safe Rust code to register non-thread-safe closures as Python callables, leading to concurrent shared mutation and data races during multithreaded execution.
A denial of service vulnerability in the ConnectBot SSH Client Library (cbssh) up to version 0.3.0 allows remote attackers to cause uncontrolled resource consumption. The library uses Kaitai Struct to parse incoming binary streams, but failed to validate the declared length of SSH fields against the physical stream size, leading to excessive memory allocation and OutOfMemoryError crashes.
An integer overflow and excessive memory allocation vulnerability in the Distinguished Encoding Rules (DER) private-key parser of ConnectBot SSH Client Library (connectbot/cbssh) allows a local attacker to cause a Denial of Service (DoS) via process termination. By inducing an application utilizing the library to parse a malformed DER-encoded private key file, the library attempts massive memory allocations, triggering an uncaught OutOfMemoryError on the JVM.