no-system-prompt-leak
This rule identifies code patterns where system prompts or AI instructions are returned in API responses, logged, or ...
Prevents system prompts from being exposed in API responses or client code.
π Rule Details
| Property | Value |
|---|---|
| Type | problem |
| Severity | π΄ HIGH |
| OWASP LLM | LLM07: System Prompt Leakage |
| CWE | CWE-200: Information Exposure |
| CVSS | 7.5 |
| Config Default | error (recommended, strict) |
Value & investment case
Why this rule pays for itself. Framework:
cicd-impact/philosophy.md.
| Dimension | Value |
|---|---|
| CWE / OWASP-LLM | CWE-200 β Information Exposure Β· OWASP LLM07: System Prompt Leakage |
| Feedback-loop tier | Editor / pre-commit (sub-second) β cheapest layer per the feedback-loop hierarchy |
| Defensive-layer leverage | ~10Γ cheaper than unit-test Β· ~1,000Γ cheaper than production rollback Β· 10,000+Γ cheaper than customer disclosure (cost-ratio anchors) |
| Niche relevance | Critical: AI/ML platforms (system prompts encode the product moat) Β· High: B2B SaaS shipping AI features, infra/devtools (AI-tooling category) Β· Medium: B2C, fintech (AI risk-modeling), healthtech (clinical-AI guardrails) |
| Investor-frame impact | System-prompt leakage β loss of competitive moat (the prompt is the product for many AI startups) + indirect IP/data exposure. AI-niche-specific rule class with no equivalent in pre-LLM analyzers; lint-time prevention is the cheapest defense for an attack class that didn't exist three years ago. |
Read also: philosophy.md Β§investor-frame Β· niche-presets.json Β· analyzer-evaluation-framework.md
π What This Rule Detects
This rule identifies code patterns where system prompts or AI instructions are returned in API responses, logged, or otherwise exposed to clients. System prompts often contain sensitive business logic and instructions that should remain server-side only.
β Incorrect Code
// System prompt in API response
return Response.json({
systemPrompt: SYSTEM_PROMPT,
response: result.text,
});
// System prompt returned directly
export function getConfig() {
return systemPrompt;
}
// System message exposed
res.json({
systemMessage: config.systemMessage,
data: result,
});
// Instructions exposed
return {
instructions: AI_INSTRUCTIONS,
output: response,
};β Correct Code
// Only response returned
return Response.json({
response: result.text,
});
// No system prompt in public API
export function getResponse() {
return { data: result.text };
}
// System prompt kept server-side
const systemPrompt = getSystemPrompt(); // Used internally
return res.json({ output: await generateWithPrompt(systemPrompt) });βοΈ Options
| Option | Type | Default | Description |
|---|---|---|---|
systemPromptPatterns | string[] | ['systemPrompt', 'system_prompt', 'SYSTEM_PROMPT', 'systemMessage', 'instructions', 'agentPrompt'] | Variable patterns suggesting system prompts |
π‘οΈ Why This Matters
Exposing system prompts allows attackers to:
- Understand AI behavior - Learn how to manipulate responses
- Craft targeted attacks - Design prompts that bypass safety measures
- Extract business logic - Understand proprietary AI configurations
- Find vulnerabilities - Identify weaknesses in prompt engineering
π Related Rules
no-dynamic-system-prompt- Prevent dynamic system prompts
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Custom Field Names
Why: Only configured pattern names are checked.
// β NOT DETECTED - Custom field name
return Response.json({
aiConfig: SYSTEM_PROMPT, // Not in default patterns
response: result.text,
});Mitigation: Configure systemPromptPatterns with custom field names.
Nested Object Access
Why: Deep property access may not be recognized.
// β NOT DETECTED - Nested exposure
return Response.json({
config: { prompt: systemPrompt }, // Nested
});Mitigation: Review response structure. Avoid nesting sensitive data.
Spread Operator
Why: Spread may include system prompt unknowingly.
// β NOT DETECTED - System prompt in spread
const config = { systemPrompt: '...', other: 'data' };
return Response.json({ ...config }); // Exposes systemPrompt!Mitigation: Never spread objects containing system prompts.
Serialized/Transformed Data
Why: Transformed data is not traced.
// β NOT DETECTED - Serialized before return
const data = JSON.stringify({ systemPrompt, result });
return Response.json({ payload: data });Mitigation: Never serialize system prompts.