Skip to content

Feedback-label forgery: REST POST /api/comments does not enforce reserved author: "user" #145

Description

@benvinegar

What

The invariant that author: "user" is "minted only by the viewer composer (genuine human keystrokes)" is enforced only in the MCP tier, not in REST or the stores.

  • POST /api/comments takes author straight from the body and stores it verbatim: server/app.ts:907sqlStore.ts:442 / storage.ts:412.
  • MCP coerces it (server/mcpHttp.ts:154 rejects named === "user"). REST does not.
  • The sandboxed send-prompt bridge correctly stamps author:"surface" (viewer/src/App.tsx:412), so this is not an agent-XSS vector.

Impact

Anyone with write access (the single deploy token, or anyone reachable on a no-token local board) can:

curl -X POST /api/comments -d "{\"surface\":\"<id>\",\"text\":\"...\",\"author\":\"user\"}"

…and inject authoritative-seeming commands into the agent's feedback stream, since collectFeedback (server/app.ts:348) delivers author === "user" comments as userFeedback, and wait_for_feedback (author=user) reads the same stream. The agent treats them as genuine human instructions. AGENTS.md flags this feedback channel as the thing to guard hardest.

Fix options

  1. Reject author:"user" on REST; have the composer send a viewer-only marker the server validates.
  2. Stop claiming "user" means "human" given no per-user auth, and treat it as "token-holder".
  3. Add a separate human-keystroke channel distinct from the REST write path.

Severity: Medium

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions