no-user-controlled-prompt-instructions
Prevent user input from controlling LLM instructions or behavior.
Prevent user input from controlling LLM instructions or behavior.
OWASP LLM Top 10 2025: LLM01 - Prompt Injection
CWE: CWE-73
Severity: 🔴 High
Rule Details
Flags cases where user input directly controls LLM behavior, mode, or instructions.
❌ Incorrect
instructions = req.body.instructions;
behavior = userBehavior;
mode = req.query.mode;✅ Correct
const ALLOWED_MODES = ['helpful', 'concise'];
if (!ALLOWED_MODES.includes(userMode)) throw Error();
mode = userMode;
behavior = SYSTEM_BEHAVIORS.default;Options
{
"secure-coding/no-user-controlled-prompt-instructions": ["error"]
}Best Practices
Use allowlists for user-selectable behaviors rather than accepting arbitrary instructions.
Version
Introduced in v2.3.0
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Prompt from Variable
Why: Prompt content from variables not traced.
// ❌ NOT DETECTED - Prompt from variable
const prompt = buildPrompt(userInput);
await generateText({ prompt });Mitigation: Validate all prompt components.
Nested Context
Why: Deep nesting obscures injection.
// ❌ NOT DETECTED - Nested
const messages = [{ role: 'user', content: userInput }];
await chat({ messages });Mitigation: Validate at all levels.
Custom AI Wrappers
Why: Custom AI clients not recognized.
// ❌ NOT DETECTED - Custom wrapper
myAI.complete(userPrompt);Mitigation: Apply rule to wrapper implementations.
no-unvalidated-user-input
Detects unvalidated user input usage (req.body, req.query, etc.) in Express, Fastify, and Next.js applications. This rule is part of [`eslint-plugin-secure-codi
no-verbose-error-messages
The rule provides **LLM-optimized error messages** (Compact 2-line format) with actionable security guidance: