CodeVetter · Repo Unpack · Risk map
rustdesk/rustdesk
The riskiest surface is the unauthenticated pre-login path (deliberately bounded by slot pools and message caps), the IPC bridge between privileged service and user processes (heavily hardened with uid/executable checks), and updater/portable paths that write executables and delete files. Heavy use of forked/patched crypto-adjacent deps (webrtc, tungstenite, kcp) and `panic=abort` release profile amplify small defects. The empty hbb_common submodule means the actual wire crypto/proto code cannot be audited in this clone.
- Unauthenticated-connection resource guards: MAX_UNAUTHORIZED_CONNS=64 global, 16 per address, LOGIN_GRACE=180s, MAX_UNAUTHORIZED_MESSAGE=128KiB, plus PunchPool caps (32 UDP + 32 TCP punches) and MAX_WEBRTC_ANSWERERS=16 — all tuned against pre-auth DoS; weakening any of these constants is a security regression.
- MITM hardening on WebRTC: the controlled side signs its DTLS fingerprint into IdPk and the controller fails closed on mismatch ('possible MITM' bails); removing the dtls_fingerprint_bound check would silently downgrade to an unauthenticated channel.
- IPC authentication is platform-specific and intricate: ipc/auth.rs has Windows executable-identity checks (ensure_peer_executable_matches_current_by_pid_opt, portable-service token handshake), Linux uid allow-listing (is_allowed_service_peer_uid, peer_uid_from_fd) and SCM_RIGHTS fd passing for DRM capture (ipc/drm.rs) — a privileged-root attack surface.
- Path-traversal-hardened file deletion: portable packer's resolve_within rebuilds meta.toml-listed paths component-by-component rejecting prefixes/roots/parents/colons because meta.toml sits in a user-writable dir and drives deletion — prior-traversal-bug-shaped code.
- Updater runs with root/service privileges: macOS update requires a root-owned /var/run/rustdesk-update.lock with O_NOFOLLOW + flock; Windows update_me/--update path and `platform::install_me` copy executables — a compromised api-server/URL could push code (update URLs come from config/options). (inferred)
- Shell-out surface: core_main/platform code spawns pkill, caffeinate, cmdkey/mstsc (rdp), gtk_sudo::exec, terminal_helper ConPTY processes, and install/uninstall scripts; args are mostly fixed strings but `run_rdp` reads rdp_username/rdp_password env vars into cmdkey args.
- panic='abort' in release profile + pervasive `.unwrap()` on locks (e.g. `server.write().unwrap()`, `conns.lock().unwrap()`) means any poisoning or panic aborts the whole process including active sessions; AGENTS.md bans unwrap but legacy code is full of it. (inferred)
- The strategy-sync path lets the self-hosted server push arbitrary Config options (`StrategyOptions.config_options` applied to Config) — a malicious/compromised api-server could flip security options like enable-lan-discovery or disable-clipboard on all clients. (inferred)
- 2FA secret handling: TOTP secret is generated per generate2fa() and stored via encrypt_vec_or_original with a hardcoded "00" key context in config — obfuscation-grade encryption at rest, not real protection.
- Legacy Sciter UI (src/ui/) still compiled when `flutter` feature is off and reachable via ui::start — deprecated but alive code paths (CUR_SESSION, SciterHandler) enlarge the maintenance/audit surface.
- Forked network stack risk: webrtc/webrtc-sctp/webrtc-util and tungstenite are pinned to rustdesk-org forks with custom congestion-control and parsing changes; upstream CVE fixes will not flow through cargo update and must be cherry-picked by rev. (inferred)