Skip to content

canvas: auth-gate state-changing POSTs, cap request bodies, restrict tmux sends (security trio)#143

Merged
davidj4tech merged 1 commit into
agent-tree-vim-navfrom
canvas-security-trio
Jul 10, 2026
Merged

canvas: auth-gate state-changing POSTs, cap request bodies, restrict tmux sends (security trio)#143
davidj4tech merged 1 commit into
agent-tree-vim-navfrom
canvas-security-trio

Conversation

@davidj4tech

Copy link
Copy Markdown
Owner

Three contained security fixes to the visual canvas server (packages/visual/src/agent_media_visual/canvas.py), one per issue. Only this file is touched.

#138 — /show /ctl /say /play were unauthenticated & CSRF-able

These state-changing POSTs changed state with no auth, unlike /input. Any web page the user visited could POST a text/plain JSON body and speak text aloud, play an attacker URL on the house speakers, or spoof images onto every screen. Now all four route through the same _authorized(self) gate as /input, returning 401 when unauthorized. /input's own gate is unchanged; read-only GET endpoints (/events, /pair, /agents, …) stay open by design.

#139 — unbounded request body → remote OOM

_read_json read Content-Length bytes with no cap, so a single POST with Content-Length: 5000000000 forced a multi-GB allocation (remote OOM on a RAM-tight host). do_POST now rejects bodies over 64 KiB with 413 before reading a byte; _read_json additionally caps its read (min(clen, _MAX_BODY)) as defence in depth.

#140 — send-to-pane not restricted to Claude panes → RCE

send_input resolved a tmux:<target> via raw tmux display-message against any session and never verified it was a Claude-Code pane — text+Enter into a bare shell is host command execution. The target is now validated against _tmux_cc_panes() (which already filters pane_current_command == "claude"); anything that isn't a live claude pane is rejected. The legitimate "reply to an agent pane" path still works.

Verification

  • python3 -m py_compile passes; module imports cleanly.
  • Drove do_POST with a fake handler: oversized /show413 with zero bytes read; unauthorized /say, /ctl, /play401; with auth present /say passes the gate and executes.

Closes #138, #139, #140

…rict tmux sends to claude panes

Three contained security fixes to the visual canvas server:

- #138: /show, /ctl, /say, /play changed state with no auth and were
  CSRF-able. Route all four through the same _authorized() gate as
  /input, returning 401 when unauthorized. Read-only GET endpoints and
  /input's own gate are unchanged.

- #139: _read_json read Content-Length bytes uncapped — one POST with a
  5 GB Content-Length forced a multi-GB alloc (remote OOM on a RAM-tight
  host). Reject bodies over 64 KiB with 413 before reading; _read_json
  also caps its read as defence in depth.

- #140: send_input resolved tmux:<target> via raw `tmux display-message`
  against any session, so text+Enter could land in a bare shell = host
  command execution. Validate the target against _tmux_cc_panes() (which
  filters cmd=="claude") and reject anything that isn't a live claude pane.

Closes #138, #139, #140
@davidj4tech davidj4tech merged commit 7c32686 into agent-tree-vim-nav Jul 10, 2026
2 checks passed
@davidj4tech davidj4tech deleted the canvas-security-trio branch July 10, 2026 14:49
davidj4tech added a commit that referenced this pull request Jul 11, 2026
…ion)

PR #143 auth-gated the state-changing POSTs (incl. /say and /play) for CSRF
safety, but the play-turn / play-last-clip client calls still used a plain
fetch — so on the merged branch they 401'd and the spinner hung. Route both
through authed() (X-Auth-Token, prompt-on-401), same as /input, and drop the
spinner on a non-ok response. Verified: /say is 401 without a token, 200 with.
davidj4tech added a commit that referenced this pull request Jul 11, 2026
Canvas: vim-key navigation for the agent tree + peek panel, play-load spinner, edge-tts PATH fixes, and the auth-gated /say · /play client integration. Bundles the #143 security trio merged into this branch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant