Status: Patched
This vulnerability has been verified as resolved and deployed.
Permission model bypass via unchecked Unix Domain Socket connections (CVE-2026-21636)
Summary
Node.js permission model fails to enforce network restrictions for Unix Domain Socket connections
Node.js permission model fails to enforce network restrictions for Unix Domain Socket (UDS) connections. With --permission enabled and without --allow-net (or any allowlists), an attacker-controlled URL or socketPath still reaches arbitrary local sockets via net, tls, or undici/fetch. This breaks the security boundary the permission model is meant to provide and enables SSRF-to-local-RCE style impact against local daemons (e.g., Docker API) while the administrator believes networking is blocked.
CVSS Score
Vulnerability Location
Sink-to-Source Analysis
PipeWrap::Connect calls uv_pipe_connect2 directly without any permission enforcement. Unlike TCP connections which explicitly check permissions, UDS connections bypass this entirely.
For comparison, TCP connect enforces permissions using ERR_ACCESS_DENIED_IF_INSUFFICIENT_PERMISSIONS. This check is absent from the UDS path in pipe_wrap.cc.
Undici connector builds net.connect with the attacker-controlled socketPath, which uses PipeWrap internally and bypasses permission checks.
Permission model initialization sets up process.permission, but pipe_wrap IPC paths never call ERR_ACCESS_DENIED_IF_INSUFFICIENT_PERMISSIONS, so the model is bypassed for all UDS operations.
Impact Analysis
Critical Impact
SSRF in a web app running with --permission lets an attacker supply http://unix:/var/run/docker.sock:/containers/json to gain Docker control, spawn containers with host mounts, and achieve host RCE. Access to local secrets daemons (Vault agent sockets, database UDS listeners) is also possible without any --allow-net flag. The primary security guarantee of --permission is bypassed for UDS, invalidating the threat model for "no network" deployments.
Attack Surface
Any Node.js application running with --permission enabled that accepts attacker-controlled URLs or socket paths via net.connect, tls.connect, or undici/fetch with socketPath options.
Preconditions
The attacker needs the ability to supply a URL (e.g., SSRF) or socketPath option to a Node.js process running with the permission model enabled. No --allow-net flag is required for the attack to succeed.
Proof of Concept
Environment Setup
Requirements: Build Node.js from source (./configure && make -j8) or use Node.js v25+ with the permission model.
Verify build:
Target Configuration
Terminal 1: Start a UDS listener (benign stand-in for a privileged daemon)
Exploit Delivery
Terminal 2: Connect with permission model enabled but no --allow-net
Minimal Repro (net.connect to UDS):
Minimal Repro (undici/fetch over UDS):
Outcome
Both repros demonstrate that UDS connections bypass the permission model entirely. The net.connect example prints CONNECTED and the undici example successfully receives the response from the socket. This allows attackers to pivot through Node's runtime to access privileged local services (Docker API, database sockets, etc.) despite the operator enabling the permission model.
Expected Response:
The connection succeeds even though --allow-net was not provided. This should result in ERR_ACCESS_DENIED.
