deno
f323745b - fix(ext/node): require --allow-net=unix for node:net unix sockets (#35835)

Commit
50 days ago
fix(ext/node): require --allow-net=unix for node:net unix sockets (#35835) Deno's native Unix-domain socket path treats a socket as both a filesystem entry and an outbound network primitive. Connecting to or listening on a Unix socket requires filesystem access to the socket path *and* an `--allow-net=unix:<path>` grant. This is deliberate: read/write access to a socket path such as `/var/run/docker.sock` should not, by itself, be enough to reach local IPC services like Docker, dbus, or podman. The native helper `check_unix_socket_path` in `ext/net/ops_unix.rs` enforces both checks. The node-compat `PipeWrap` path — the native backing for `node:net` Unix sockets — only performed the filesystem `check_open` check. It never required the Unix-socket network grant. As a result, `node:net.createConnection(path)` and `net.createServer().listen(path)` could reach a Unix socket under `--deny-net` as long as filesystem permission for the socket path was granted, diverging from the native `Deno.connect({ transport: "unix" })` and `Deno.listen({ transport: "unix" })` behaviour. Rather than duplicating the check pair, `check_unix_socket_path` is now public in `deno_net` (returning `PermissionCheckError` directly; its `ext/net` call sites keep working through the existing `#[from]` conversion into `NetError`) and `PipeWrap::connect`, `bind`, and `listen` call it, so the node-compat path enforces exactly the same invariant as the native one and the two cannot drift apart again. Sharing the helper also fixes abstract socket handling (Linux, leading NUL). Abstract sockets have no filesystem entry, so — like the native path — they now skip the filesystem check and are governed by the network check alone. Previously the node-compat path incorrectly required filesystem permission on the NUL-prefixed pseudo-path, which no filesystem grant could meaningfully scope. Note that on Windows `PipeWrap` backs `node:net` named pipes (`\\.\pipe\...`), which now also require a net grant in addition to the filesystem check. This is intentional: the threat model is the same (e.g. Docker Desktop listens on `\\.\pipe\docker_engine`). `unix:` net rules parse on all platforms and accept any absolute path, so named pipes can be granted with `--allow-net=unix:\\.\pipe\<name>` or a blanket `--allow-net`. Spec tests: one step grants full `--allow-read`/`--allow-write` with `--deny-net` and asserts that `connect` and `bind` through the low-level pipe binding are denied, including for an abstract path. A Linux-only step grants only `--allow-net` (no filesystem permissions) and asserts that binding an abstract socket succeeds while binding a path-based socket is still denied by the filesystem check.
Author
Parents
Loading