Skip to content

Security: tarides/sudo-proxy

Security

docs/security.md

Security considerations

← README

For a point-in-time adversarial audit of the source tree, see security-audit.md. For the longer-term plan to formalise this security model — from code review up to mechanized verification — see formalisation-roadmap.md, the structured threat-model.md (STRIDE + attack tree), and the GSN assurance-case.md.

Environment: the request env is gated by a hard allowlist (LANG, LC_*, TZ, HOME, DEBIAN_FRONTEND, TERM). Anything else — including LD_PRELOAD, LD_LIBRARY_PATH, PATH, etc. — produces an error response; nothing is silently stripped. For pkexec and direct execution the process environment is cleared before applying the allowlist. For sudo mode the process environment is inherited, but sudo's own env_reset policy handles cleanup. SSH_AUTH_SOCK is rejected with a specific error; agent forwarding goes through the dedicated forward_agent field instead (see "SSH agent forwarding" in usage.md).

No shell invocation: commands are executed via Command::new(argv[0]).args(…), never sh -c. This prevents ;, |, && injection.

Input validation: argv and env strings are rejected if they contain control characters (0x00–0x1F except tab), zero-width characters (U+200B–U+200F), or bidi override characters (U+202A–U+202E, U+2066–U+2069) that could mislead the user during TUI approval.

Replay protection: request UUIDs are tracked in a set that is cleared every 1000 entries. Duplicate IDs are rejected. Requests must carry a non-empty time; missing, unparseable, or older-than-60-seconds values are rejected.

Socket security: the socket file is created with mode 0600 (owner-only). $XDG_RUNTIME_DIR is already restricted to the user.

Execution isolation: child processes run with cwd /, umask 0077, and stdout/stderr piped — they do not inherit the socket file descriptor. stdin is null except for sudo mode, which inherits the terminal so sudo can prompt for a password.

TUI hardening: the Y/N prompt reads a single keypress in non-canonical terminal mode (no Enter required) and times out after 60 seconds (default deny). The resolved absolute path of argv[0] is displayed alongside the requested name, followed by -> and the canonical target when it differs (i.e. when the PATH-found file is itself a symlink), so a same-UID adversary who substitutes /usr/local/bin/foo -> /tmp/evil cannot hide the redirection by either relying on a PATH search or passing the absolute path directly. If canonicalize fails (broken symlink, EACCES) the prompt says so explicitly rather than silently displaying the as-found name. If argv[0] is not found in PATH, the prompt shows (not found in PATH) as a warning.

There aren't any published security advisories