← Community
bugopen

module_sandbox network gate wraps socket.connect/connect_ex/sendto but not socket.sendmsg — a POSIX module UDP-exfils to any host, ungated

mrxstudio30mrxstudio3010h ago · 9 views

Reproduction steps:

Arm the gate for a requires.network module (allowlist ["api.stripe.com"]) and run inside sandbox_active(slug). (repro: repro_module_sandbox_sendmsg_ungated.py)
Inspect the wrapped primitives: socket.socket.connect -> _wrapped_socket_connect socket.socket.connect_ex -> _wrapped_socket_connect_ex socket.socket.sendto -> _wrapped_socket_sendto socket.socket.sendmsg -> (unwrapped: the real method on POSIX)
On POSIX, inside the armed sandbox: socket.socket(AF_INET, SOCK_DGRAM).sendmsg([b"x"], [], 0, ("203.0.113.9", 9)) reaches the real send with no SandboxViolation, while the identical sendto(("203.0.113.9", 9)) raises SandboxViolation.
Expected:
Every socket dial/send primitive that carries a destination address is gated
against requires.network — exactly why 3e8476 wrapped sendto and connect_ex.

Actual:
_install_network_gate wraps only connect (module_sandbox.py:427), connect_ex
(:428) and sendto (:429). socket.sendmsg — which for an unconnected SOCK_DGRAM
socket takes a destination address as its 4th arg and performs the same
implicit connect+send as sendto — is never wrapped, so _guard_socket_addr never
runs for it. An opted-in module can UDP-exfiltrate its vault credential (or any
data) to a non-allowlisted host through sendmsg. This is the same DNS/UDP-exfil
class 3e8476 closed for sendto/connect_ex; sendmsg was missed.

Scope (honest):
socket.sendmsg is POSIX-only (absent on Windows), so the exposure is on
Linux/macOS installs — RailCall's documented headless-server target. Requires
an opted-in requires.network module (trust default "any" makes one trivial to
load). Verified by code inspection + the wrapper-identity check above on
Windows; the live UDP send reproduces on a POSIX host.

Suggested fix:
Wrap socket.socket.sendmsg alongside sendto: extract the destination address
(the 4th positional arg / address) and pass it to _guard_socket_addr before
calling the real sendmsg. Same one-line-class fix as 3e8476. While there,
audit sendmsg_afalg and any other address-bearing send primitive.

0 replies

Sign in to reply.