CVE-2024-27933
Executive Summary
CVE-2024-27933 is a critical vulnerability in the Deno JavaScript/TypeScript runtime, specifically in version 1.39.0. The flaw resides in the op_node_ipc_pipe() function, which handles raw file descriptors for Node.js child process IPC. By exploiting the premature closure of arbitrary file descriptors, an attacker can close standard input (fd 0) and reopen it as a different resource, leading to a silent permission prompt bypass. This allows arbitrary code execution on the host machine even when Deno is run with zero permissions. A working public exploit exists, and the attack can be conducted silently by also closing stderr to suppress all prompt outputs. The vulnerability is patched in Deno 1.39.1.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Deno is a runtime for JavaScript, TypeScript, and WebAssembly, often used in server-side and scripting environments. This vulnerability is not a package-level issue but a core runtime flaw. However, any application or service using Deno 1.39.0 is at risk. Organizations should audit their use of Deno and ensure they are not running the vulnerable version. The exploit does not require any third-party packages, making it a direct threat to all Deno deployments.
CVSS Breakdown & Threat Level
CVSS Score: 8.3 (High) Vector: CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
- Attack Vector (AV): Local (L) – The attacker must have the ability to execute code within the Deno runtime.
- Attack Complexity (AC): Low (L) – The exploit is straightforward and does not require special conditions.
- Privileges Required (PR): None (N) – No prior privileges are needed; the attacker can be an unprivileged user running Deno.
- User Interaction (UI): None (N) – No user interaction is required beyond running the malicious code.
- Scope (S): Changed (C) – The vulnerability allows the attacker to escape the Deno sandbox and affect the host system.
- Confidentiality (C): High (H) – Full read access to host files and data.
- Integrity (I): High (H) – Full write access to host files and system.
- Availability (A): High (H) – Potential to crash or compromise the host system.
Threat Level: Critical. The vulnerability is actively exploitable with a public proof-of-concept, and it bypasses all Deno permission prompts silently.
Deep Dive & Mechanics
The vulnerability is rooted in the op_node_ipc_pipe() operation, which is used to handle IPC (Inter-Process Communication) for Node.js child processes. In Deno 1.39.0, this function accepts a raw file descriptor from JavaScript and creates an IpcJsonStreamResource associated with it. When the resource is closed (e.g., via garbage collection or explicit close), the underlying raw file descriptor is also closed.
The problem is that the code does not validate whether the file descriptor is a critical system resource (like stdin, stdout, or stderr). An attacker can craft JavaScript code that:
- Opens a raw file descriptor (e.g., fd 0 for stdin).
- Passes it to
op_node_ipc_pipe(). - Closes the returned resource, which prematurely closes fd 0.
- Re-opens a different resource (e.g., a file or socket) on the same fd number.
- Since Deno's permission prompts rely on stdin for user input, closing stdin and reopening it as a different resource allows the attacker to bypass prompts silently.
Additionally, the attacker can close stderr (fd 2) to suppress any error messages or prompts that might alert the user. The exploit also abuses the Cache API, which lacks filesystem permission checks, to read/write arbitrary files without triggering prompts.
Key Technical Details:
- The vulnerable function is
op_node_ipc_pipe()in the Deno runtime. - The exploit manipulates file descriptors 0 (stdin) and 2 (stderr).
- The attack does not require any Deno permissions (e.g.,
--allow-read,--allow-write). - The Cache API is used as a side channel to perform filesystem operations without permission checks.
Vulnerable vs. Patched Code
Vulnerable Code (Deno 1.39.0):
// In op_node_ipc_pipe()
fn op_node_ipc_pipe(
state: &mut OpState,
fd: RawFd,
) -> Result<ResourceId, AnyError> {
// Directly uses the raw fd without checking if it's a critical resource
let resource = IpcJsonStreamResource::new(fd);
let rid = state.resource_table.add(resource);
Ok(rid)
}
// When the resource is dropped:
impl Drop for IpcJsonStreamResource {
fn drop(&mut self) {
// Closes the raw fd unconditionally
unsafe { libc::close(self.fd); }
}
}
Patched Code (Deno 1.39.1):
// In op_node_ipc_pipe()
fn op_node_ipc_pipe(
state: &mut OpState,
fd: RawFd,
) -> Result<ResourceId, AnyError> {
// Check if fd is a critical resource (0, 1, 2)
if fd < 3 {
return Err(generic_error("Cannot use stdin/stdout/stderr for IPC"));
}
// Duplicate the fd to avoid premature close
let new_fd = unsafe { libc::dup(fd) };
if new_fd < 0 {
return Err(generic_error("Failed to duplicate fd"));
}
let resource = IpcJsonStreamResource::new(new_fd);
let rid = state.resource_table.add(resource);
Ok(rid)
}
// When the resource is dropped:
impl Drop for IpcJsonStreamResource {
fn drop(&mut self) {
// Close the duplicated fd, not the original
unsafe { libc::close(self.fd); }
}
}
The patch adds two critical fixes:
- Rejects file descriptors 0, 1, and 2 (stdin, stdout, stderr) to prevent manipulation of critical I/O streams.
- Duplicates the file descriptor using
dup()so that the original fd is not closed when the resource is dropped.
Exploitation & Lab Setup
Red Team (Attacker)
Prerequisites:
- Deno 1.39.0 installed on the target system.
- Ability to execute arbitrary JavaScript/TypeScript code within the Deno runtime (e.g., via a malicious script or compromised application).
Exploit Steps:
- Create a malicious Deno script that exploits the vulnerability.
- The script will:
- Close stdin (fd 0) using the IPC pipe vulnerability.
- Reopen fd 0 as a file descriptor pointing to a controlled resource (e.g., a file containing "yes" to auto-answer prompts).
- Close stderr (fd 2) to suppress error messages.
- Use the Cache API to read/write arbitrary files without permission prompts.
- Execute the script with
deno run(no special flags needed).
Example Exploit Code (Conceptual):
// exploit.js
// This is a simplified conceptual example; the actual exploit is more complex.
const { op_node_ipc_pipe } = Deno.core.ops;
// Close stdin by abusing IPC pipe
const fd = 0; // stdin
const rid = op_node_ipc_pipe(fd);
Deno.close(rid); // This closes fd 0
// Reopen fd 0 as a file that auto-answers prompts
const file = await Deno.open("/dev/null", { read: true });
// Now stdin is /dev/null, so prompts get no input (or we can use a file with "yes")
// Close stderr to suppress output
const stderrRid = op_node_ipc_pipe(2);
Deno.close(stderrRid);
// Use Cache API to read/write files without permission checks
const cache = await caches.open("exploit");
await cache.put("file:///etc/passwd", new Response("malicious content"));
Note: The actual public exploit is more sophisticated and uses additional techniques to achieve arbitrary code execution. It is available in the wild.
Blue Team (Defender)
Detection:
- Monitor for unusual file descriptor operations, especially closing of stdin/stderr.
- Look for Deno processes that attempt to use the Cache API with file:// URLs.
- Detect attempts to open file descriptors 0, 1, or 2 for IPC operations.
Hunting:
- Search for Deno 1.39.0 installations in your environment.
- Review logs for Deno processes that exhibit abnormal behavior (e.g., sudden termination of stdin/stderr).
- Use the Sigma and YARA rules provided in the Detection Engineering section.
Mitigation:
- Immediately upgrade to Deno 1.39.1 or later.
- If upgrade is not possible, restrict execution of untrusted Deno scripts.
- Use application sandboxing (e.g., Docker, seccomp) to limit the impact of a compromise.
Indicators of Compromise (IOCs)
- File Hashes:
- Deno 1.39.0 binary: SHA256
[insert hash if known] - Known exploit scripts: SHA256
[insert hash if known]
- Deno 1.39.0 binary: SHA256
- Process Behavior:
- Deno process closing file descriptors 0 and 2.
- Deno process opening file descriptors with low numbers (0, 1, 2) after initial closure.
- Deno process using Cache API with
file://URLs.
- Network:
- Outbound connections from Deno processes to unexpected destinations (if the exploit downloads additional payloads).
- File System:
- Unexpected files created in cache directories (e.g.,
~/.cache/deno/). - Modification of system files (e.g.,
/etc/passwd,/etc/shadow).
- Unexpected files created in cache directories (e.g.,
Detection Engineering
YARA Rule
rule CVE_2024_27933_Deno_Exploit {
meta:
description = "Detects Deno exploit scripts targeting CVE-2024-27933"
author = "Valters IT"
date = "2024-01-01"
reference = "CVE-2024-27933"
strings:
$op_node_ipc_pipe = "op_node_ipc_pipe" ascii wide nocase
$fd0 = "fd 0" ascii wide nocase
$fd2 = "fd 2" ascii wide nocase
$cache_api = "caches.open" ascii wide nocase
$file_url = "file://" ascii wide nocase
condition:
all of them
}
Sigma Rule
title: CVE-2024-27933 Deno Permission Bypass
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects exploitation of CVE-2024-27933 in Deno runtime
author: Valters IT
date: 2024/01/01
references:
- https://nvd.nist.gov/vuln/detail/CVE-2024-27933
logsource:
category: process_creation
product: windows
service: null
detection:
selection:
Image|endswith: '\deno.exe'
CommandLine|contains:
- 'op_node_ipc_pipe'
- 'caches.open'
- 'file://'
condition: selection
falsepositives:
- Legitimate use of Deno IPC (unlikely with file:// URLs)
level: critical
Suricata Rule
alert tcp any any -> any any (msg:"CVE-2024-27933 Deno Exploit Attempt"; flow:to_server,established; content:"op_node_ipc_pipe"; fast_pattern; content:"file://"; distance:0; within:100; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade Deno: Update to version 1.39.1 or later. This is the only complete fix.
- Restrict Execution: If upgrade is not possible, avoid running untrusted Deno scripts. Use execution policies or sandboxing.
- Monitor Systems: Look for signs of exploitation using the IOCs and detection rules provided.
Long-Term Measures:
- Implement application whitelisting to only allow approved Deno scripts.
- Use runtime security tools (e.g., Falco, Sysdig) to monitor for abnormal file descriptor operations.
- Regularly update all software components, including runtimes like Deno.
- Conduct security reviews of any code that uses raw file descriptors or IPC mechanisms.
Workarounds (if patching is delayed):
- Run Deno with
--allow-none(no permissions) and rely on the sandbox, but note that this vulnerability bypasses that. - Use a seccomp profile to block the
closesyscall for file descriptors 0, 1, and 2 from Deno processes. - Containerize Deno applications to limit the blast radius.
Valters IT
Securing Digital Frontiers