Passing AI model output directly to eval(), Function(), shell execution utilities, or child process spawners creates a remote code execution (RCE) vulnerability gated entirely on prompt injection success. OWASP LLM02:2025 (Insecure Output Handling) names this as the most severe consequence class; MITRE ATLAS AML.T0051 classifies it as adversarial exploitation of agentic AI systems. CWE-94 (Improper Control of Code Generation) applies directly. A successful prompt injection in an application that executes model output does not just override behavior—it achieves arbitrary code execution on the application server with the process's full privileges. NIST AI RMF MAP 5.1 requires explicitly mapping and controlling the actions an AI system can initiate, with code execution at the top of that list.
Critical because any successful prompt injection in a code-execution pipeline escalates immediately to server-side arbitrary code execution, the most severe possible consequence of an injection vulnerability.
AI output must never be treated as executable. Validate it against a strict schema before any processing, and if code execution is an intended feature, route it through a sandboxed environment with no network access and no filesystem write permissions.
// src/lib/ai-actions.ts — safe model output handling
const ActionSchema = z.object({
action: z.enum(['search_docs', 'get_user', 'create_draft']), // strict allowlist
targetId: z.string().uuid(),
})
const raw = completion.choices[0]?.message?.content ?? ''
let parsed: unknown
try {
parsed = JSON.parse(raw)
} catch {
throw new Error('Model returned non-JSON output')
}
const validated = ActionSchema.safeParse(parsed)
if (!validated.success) {
// Model output failed schema validation — do not proceed
throw new Error('Unexpected model output shape')
}
// Execute only validated, allowlisted actions
await executeAction(validated.data.action, validated.data.targetId)
For intentional code sandbox features, use e2b or an isolated container with explicit capability restrictions—never Node.js built-in execution mechanisms with untrusted input.
ID: ai-prompt-injection.output-filtering.no-dynamic-code-execution
Severity: critical
What to look for: Enumerate every location where LLM output could trigger code execution (eval, exec, Function constructor, subprocess). For each, search for any code path where the text content from an AI model response is passed to functions capable of dynamic code execution. This includes: passing model output to the JavaScript Function constructor, using setTimeout or setInterval with a string argument derived from model output, passing model output to server-side code execution utilities (child process spawning, shell execution libraries), or using model output as a template in server-side rendering engines that execute arbitrary expressions. Look for variable assignments from completion.choices[0].message.content or equivalent, then trace whether that value reaches any execution-capable function.
Pass criteria: AI model output is only used for: display (rendering as text/HTML with proper escaping), storage (writing to database), or parsing with a strict schema validator. No path exists from model output to any code or command execution function — fewer than 1 unsandboxed code execution path should accept raw LLM output. Report: "X LLM-to-code paths found, all Y are sandboxed or blocked."
Fail criteria: Any code path exists from model output (the text returned by the AI provider) to a function capable of executing code or shell commands.
Skip (N/A) when: No AI provider integration detected.
Detail on fail: Describe the code path without including the dangerous function names. Example: "lib/tools.ts runModelAction() passes the model's output string to a child process execution function in the Node.js standard library" or "AI response content is passed to a dynamic evaluation function in app/api/code-runner/route.ts"
Remediation: Passing AI output to code execution functions is the most dangerous prompt injection consequence — a successful injection could run arbitrary code on your server. AI output must never be treated as executable.
If your application intentionally runs code (e.g., a code sandbox), ensure strict sandboxing in src/lib/sandbox.ts:
// Bad: executing LLM output directly
const result = eval(llmOutput);
// Good: validate against allowlist and run in sandbox
const parsed = JSON.parse(llmOutput);
if (!ALLOWED_ACTIONS.includes(parsed.action)) throw new Error('Blocked');
const result = await sandbox.execute(parsed.action, parsed.args);