Skip to content

fix: validate request body in POST /projects/:projectId/chat#155

Open
Shawnaldinho wants to merge 1 commit into
willchen96:mainfrom
Shawnaldinho:fix/projectchat-input-validation
Open

fix: validate request body in POST /projects/:projectId/chat#155
Shawnaldinho wants to merge 1 commit into
willchen96:mainfrom
Shawnaldinho:fix/projectchat-input-validation

Conversation

@Shawnaldinho
Copy link
Copy Markdown

Summary

projectChat.ts:32-39 reads `req.body` via a bare `as { ... }` cast, while sibling routes (`chat.ts`, `user.ts`) use hand-written parsers. A misshapen body — wrong types for `messages`, `displayed_doc`, `attached_documents` — therefore reaches the DB writes and the LLM call.

Changes

  • Add per-field parsers in `backend/src/routes/projectChat.ts` matching the `parseFoo(value: unknown): { ok: true; ... } | { ok: false; detail }` pattern already used by `routes/chat.ts`: `parseChatMessages`, `parseOptionalChatId`, `parseOptionalModel`, `parseDocRef`, `parseOptionalDisplayedDoc`, `parseOptionalAttachedDocuments`.
  • Validate every field before any DB or LLM work; return `400` with the parser's `detail` message on the first failure.
  • Downstream variable names (`messages`, `chat_id`, `model`, `displayed_doc`, `attached_documents`) are preserved so the rest of the handler is unchanged.

Why

Concrete failures the previous cast permitted:

  • `messages` as a non-array → `[...messages].reverse()` throws inside the handler after the chat row has already been inserted.
  • `attached_documents` containing non-object entries → `.map((d) => ...)` crashes on `d.document_id`.
  • `displayed_doc` as a string → the route builds a malformed user message and sends it to the model.

Matches the existing style rather than introducing a new validation library, per CONTRIBUTING.md guidance to keep changes targeted.

Testing

  • `npm run build --prefix backend` passes.
  • Walked each parser through the previously crash-inducing shapes and confirmed each now returns a 400 with a useful `detail`.

Addresses the input-validation concern from https://insights.flank.ai/where-mikeoss-falls-short.html (gap 7) for this specific route. Other routes already validate by hand.

The route was reading req.body via a bare `as { ... }` cast, so an
unauthenticated misshapen body could reach the DB writes and the LLM
call (e.g. messages as a non-array would crash inside
[...messages].reverse(), attached_documents with non-object entries
would crash when destructured, displayed_doc could be any value).

Mirror the hand-written parser pattern already used by routes/chat.ts:
- parseChatMessages, parseOptionalChatId, parseOptionalModel
- parseDocRef + parseOptionalDisplayedDoc, parseOptionalAttachedDocuments

Each returns either { ok: true, ... } or { ok: false, detail }; on
any failure the handler returns 400 with the parser's detail message
before touching the DB or the LLM. The downstream variable names
(messages, chat_id, model, displayed_doc, attached_documents) keep
the same shape as before, so the rest of the handler is unchanged.
Dshamir added a commit to Dshamir/AI-Legal that referenced this pull request May 24, 2026
- GET /chat now accepts a `before` cursor (ISO timestamp) for keyset
  pagination. Default limit set to 50 (PR willchen96#110).
- POST /projects/:projectId/chat validates request body via Zod
  schema with the validate() middleware (PR willchen96#155).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dshamir added a commit to Dshamir/AI-Legal that referenced this pull request May 24, 2026
…tegration

- CHANGELOG: add security hardening and feature entries for PRs willchen96#158,
  willchen96#81, willchen96#76, willchen96#79, willchen96#145, willchen96#112, willchen96#111, willchen96#110, willchen96#155, willchen96#157, willchen96#59
- ROADMAP: mark 12 new items as completed
- CLAUDE.md: add sanitize.ts, streamTimeout.ts, credits.ts to lib index,
  update test count to 40
- README: update API endpoints table (chat pagination, workflow export),
  security row (HKDF, RLS, prompt defense), encryption row

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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