Security [HIGH]: Assistant chat message content unbounded — AI cost/memory DoS #38
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
messages[].contentandpageContextin assistant-procedure-support.ts have no.max(). An authenticated user can submit 50 MB per message × 200 messages ⇒ 10 GB of text → AI-cost DoS, memory blow-up during JSON parse & prompt assembly.Evidence
packages/api/src/router/assistant-procedure-support.ts:47-54 — content: z.string() (no max)packages/api/src/router/assistant-procedure-support.ts:54 — pageContext: z.string().optional() (no max)packages/api/src/router/project-cover.ts:67-69 — DALL-E/Gemini prompt user-input concatenated directly, no injection-guardImpact
Any authenticated user can: (a) burn thousands of dollars in AI-provider costs in minutes, (b) OOM the API process via JSON parsing, (c) inject directives into DALL-E/Gemini via project-cover prompt (no
checkPromptInjectionthere).Proposed Fix
content: z.string().max(10_000),pageContext: z.string().max(2_000). Compute aggregate message budget (e.g., 50 KB) and reject when exceeded. ApplycheckPromptInjection()toproject-cover.prompt.Acceptance Criteria
.max()Parent Epic: #1
Source: Full-Codebase Security Audit 2026-04-16 (B-2, B-15)
Resolved.
packages/api/src/router/assistant-procedure-support.ts:49-77now enforces:content: z.string().max(10_000)per messagepageContext: z.string().max(2_000)conversationId: z.string().max(120)superRefine: 200 KB across all messages + pageContext.min(1).max(200)messages arraypackages/api/src/router/project-cover.ts:37-56now runscheckPromptInjection(input.prompt)on the user's additional-direction field and rejects with BAD_REQUEST on a hit.Tests:
packages/api/src/__tests__/assistant-input-bounds.test.tscovers all four limits with both accept + reject cases.All acceptance criteria met — closing.