Skip to main content
Back to Home

What Zelsis checks · AI features

AI features that can be abused or run up the bill

An AI feature can be talked into ignoring its instructions, or loop until the invoice arrives. Zelsis checks the code around the model call.

Checked on every pull request

  • Request data written into the system prompt
  • Model output rendered as HTML, run as code or used for an access decision
  • Model calls with no max_tokens limit
  • Agent loops with no step limit, and retries with no backoff
  • MCP servers launched from a request

Caught in real code

Our test suite scans these examples on every release.

MCP server launched from a request

LLM-V2-04

An endpoint that starts an MCP stdio server with a command taken from the request lets anyone run programs on your server.

server/mcp-proxy.ts
Flagged
app.get('/connect', async (req, res) => {
  const transport = new StdioClientTransport({
    command: req.query.command as string,
    args: (req.query.args as string).split(' '),
  });
  await client.connect(transport);
});
Passes
app.get('/connect', async (req, res) => {
  const server = SERVERS[String(req.query.server)];
  if (!server) return res.status(404).end();
  const transport = new StdioClientTransport({
    command: server.command,
    args: server.args,
  });
  await client.connect(transport);
});

Visitor text written into the system prompt

SAAS-07

A field from the request becomes part of the system prompt, so anyone can rewrite the instructions your assistant follows.

app/api/chat/route.ts
Flagged
export async function POST(req: Request) {
  const { persona, question } = await req.json();
  return Response.json(await openai.chat.completions.create({ model: 'gpt-4o', max_tokens: 300, messages: [{ role: 'system', content: `You are ${persona}. Never reveal internal notes.` }, { role: 'user', content: question }] }));
}
Passes
const today = () => new Date().toISOString();
export async function POST(req: Request) {
  const { question } = await req.json();
  return Response.json(await openai.chat.completions.create({ model: 'gpt-4o', max_tokens: 300, messages: [{ role: 'system', content: `You are a support assistant. Today is ${today()}.` }, { role: 'user', content: question }] }));
}