Lessons · LLM01: Prompt Injection · warning
Anything a client sends, of any shape or size, lands in your model call.
Caught by request-body-to-llm-without-schema · CWE-20, CWE-77
Your route reads the request body and passes it to the model without checking what it is.
Your own frontend sends a nice short question. An attacker does not use your frontend. They send whatever they want straight to the endpoint: a 200,000 character message, extra fields, a system role in the messages array, a different model name.
Validation at the edge is the one place you decide what your app accepts. Without it, the model call accepts everything.
Your chat route takes { messages } from the body and passes it straight to the model.
export async function POST(req: Request) {
const { messages } = await req.json();
return streamText({ model, messages }).toTextStreamResponse();
}
The cost: Prompt injection with no effort, plus a direct way to run up your bill.
Paste this into Claude Code, Cursor, or whatever wrote the code. When llm-audit finds the mistake in your project, npx llm-audit prompt gives you the same prompt with every file and line filled in.
Fix this in my project: the request body is passed to the model without validation.
Please:
1. Parse the body with an explicit schema (zod or valibot) before using it.
2. Set a maximum length on every free-text field and a maximum number of messages.
3. Only accept "user" and "assistant" roles from the client. Add the system prompt on the server.
4. Reject the request with a 400 if validation fails.
5. Add rate limiting to this endpoint.
Show me the diff and the schema.A prompt that looks for the same mistake everywhere else, without changing anything yet.
Check this project's API routes that call an AI model, before I ship it.
Look for:
- Request bodies, form data, or query parameters passed to a model call without schema validation.
- Message arrays from the client accepted as is, including system messages.
- Free-text fields with no maximum length.
- Model endpoints with no rate limiting.
For each one, give me the file and line and explain what a request sent directly to the endpoint, not through my UI, could do. Do not change any code yet.npx llm-audit scan
Runs on your machine with Semgrep. Nothing is uploaded.