Skip to content

Operational follow-ups for paste-image endpoint (#84) #88

Description

@Ark0N

Operational gaps in the paste-image endpoint introduced in #84 — non-security, but worth filing so they don't get lost.

1. No rate-limit and no GC for .claude-images/

The endpoint enforces a 10MB per-request cap (src/web/server.ts:929-936) but no aggregate cap, no per-IP token-bucket, and cleanup only runs when killMux=true on session destroy. Soft-closed sessions leave their image dirs on disk indefinitely. An authenticated user (or anyone if CODEMAN_PASSWORD is unset and the instance is tunneled) can loop 10MB POSTs to fill the disk.

Fix: add a per-IP token-bucket on /api/sessions/:id/paste-image (e.g., 30/min, 100MB/hr); reject if du -s .claude-images/ exceeds a per-session cap; periodic GC of files older than 7 days even without killMux=true.

2. Filename collision on same-millisecond uploads

paste-${Date.now()}${ext} (src/web/routes/session-routes.ts:~1545) collides under concurrent paste from two browser tabs. Last-write-wins overwrites the prior file silently, and the response's path still references the (now-overwritten) name — the first uploader's terminal @-mentions a file whose contents are the second uploader's image.

Fix: append randomBytes(8).toString('hex') (or use randomUUID()) so concurrent uploads never collide.

3. Bracketed-paste bypass on Ctrl+V

The Ctrl+V interceptor in src/web/public/terminal-ui.js:86-92 swallows all paste events and re-sends text via sendInput(), which strips xterm's bracketed-paste markers. Claude CLI / bash can no longer distinguish "typed" from "pasted" text — relevant to prompt-injection defences in Claude Code, which treat bracketed-paste content differently.

Fix: detect "no image" early and return true from customKeyEventHandler so xterm's native paste flow handles the text path with bracketed-paste preserved.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions