Gate embedded-terminal endpoints to local origins when auth disabled
Committed by nesquena-hermes
fix(security): gate embedded-terminal endpoints to local origins when auth disabled
The embedded workspace terminal spawns a PTY shell that runs arbitrary
commands as the server-process user. check_auth() returns True
unconditionally when no password/passkey is configured (the default
out-of-the-box state), so without a network-scope gate the terminal
endpoints were reachable by any unauthenticated caller able to hit the
port — which on a passwordless public bind is remote code execution.
Apply the same local-origin gate the onboarding/bootstrap endpoints use
(_onboarding_gate_allows) to /api/terminal/{start,input,resize,close} and
/api/terminal/output: with auth disabled, accept only loopback/private
origins, ignore spoofable X-Forwarded-For/X-Real-IP unless
HERMES_WEBUI_TRUST_FORWARDED_FOR=1, and honor HERMES_WEBUI_ONBOARDING_OPEN=1
as the explicit opt-out for a deliberately-exposed server. Auth-enabled
servers (cookie already verified upstream) and genuine same-host clients
are unaffected.
Also fixes a latent test-isolation leak in
test_extension_route_remains_behind_webui_auth: it set HERMES_WEBUI_PASSWORD
but never invalidated the process-wide password-hash cache, so its result
depended on suite execution order (exposed when the new test file shifted
ordering). Invalidate before+after so it reads the env var deterministically.
12 new gate tests in tests/test_cvd3_terminal_local_origin_gate.py.Editor assessment
This commit patches CVE-2026-58123. The subject is precise: it names the embedded-terminal endpoints, the condition of auth being disabled, and the gate applied, local origins, so the change is fully legible before reading further. The body goes well beyond restating that, explaining that check_auth returns true when no credential is configured and that a passwordless public bind therefore turned the PTY endpoints into remote code execution. It then documents which routes were gated, which headers are ignored unless explicitly trusted, the opt-out environment variable, and that authenticated and same-host clients are unaffected. Tests are called out, twelve new gate tests, along with an unrelated test-isolation fix. Exemplary rationale, side effects, and verification.