mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-25 06:42:52 +08:00
The CLI and TUI build an SSH ProxyCommand string by interpolating fields from CreateSshSessionResponse into a shell command. Three fields - sandbox_id, token, and the assembled gateway_url (composed from gateway_scheme, gateway_host, gateway_port, connect_path) - were not passed through shell_escape, even though exe_command and gateway_name were. The resulting string is handed to `ssh -o ProxyCommand=...` which OpenSSH routes through `/bin/sh -c`, so a hostile or compromised gateway could inject shell metacharacters and execute arbitrary commands under the developer's workstation account. - Add build_proxy_command in openshell-core::forward that wraps every interpolated value in shell_escape. Use it at all four ProxyCommand sites: openshell-cli/src/ssh.rs (ssh_session_config) and the three TUI sites in openshell-tui/src/lib.rs (shell connect, sandbox exec, port-forward reconciliation). - Add validate_ssh_session_response in openshell-core::forward, called at each site immediately after response.into_inner(). Enforces a conservative charset per field (sandbox_id, token, gateway_host, gateway_scheme, gateway_port, connect_path, host_key_fingerprint) so malformed responses fail loudly at the gRPC trust boundary before shell escaping is attempted. Belt-and-suspenders with the escape. - Harden render_ssh_config so `gateway` and `name` are shell-escaped even though validate_gateway_name currently gates `gateway`. - Document the charset contract on CreateSshSessionResponse in proto/openshell.proto: servers must uphold these rules and clients reject responses that violate them. - Add regression unit tests covering adversarial values in every field and a build_proxy_command test asserting no shell metacharacter remains outside single-quoted regions. Tracks OS-100.