fix(auth): protect WebSocket /terminal/ws with session cookie check

BaseHTTPMiddleware only handles HTTP scope — WebSocket connections
bypassed auth entirely. Inline check before websocket.accept() reads
the muxplex_session cookie and closes with code 4001 if invalid.
Localhost (127.0.0.1, ::1) still bypasses as intended.
This commit is contained in:
Brian Krabach
2026-03-29 04:23:41 -07:00
parent 575cebbcac
commit 6c0bc80f21
2 changed files with 98 additions and 0 deletions
+11
View File
@@ -37,6 +37,7 @@ from muxplex.auth import (
load_or_create_secret,
load_password,
pam_available,
verify_session_cookie,
)
from muxplex.bells import apply_bell_clear_rule, process_bell_flags
from muxplex.sessions import (
@@ -437,6 +438,16 @@ async def terminal_ws_proxy(websocket: WebSocket) -> None:
Accepts with subprotocol 'tty' (required by ttyd), then opens a connection
to ws://localhost:{TTYD_PORT}/ws and relays frames bidirectionally.
"""
# Auth check before accepting — BaseHTTPMiddleware doesn't cover WebSocket scope
host = websocket.client.host if websocket.client else ""
if host not in ("127.0.0.1", "::1"):
session_cookie = websocket.cookies.get("muxplex_session")
if not session_cookie or not verify_session_cookie(
_auth_secret, session_cookie, _auth_ttl
):
await websocket.close(code=4001)
return
await websocket.accept(subprotocol="tty")
ttyd_url = f"ws://localhost:{TTYD_PORT}/ws"