OWASP LLM Top 10 Coverage
| OWASP Risk | Rule | Coverage | Whatβs Detected |
|---|---|---|---|
| Prompt Injection | LLM01 | π’ Strong | 6 injection vectors with role-aware AST taint analysis |
| Sensitive Info Disclosure | LLM02 | π‘ Partial | 4 LLM API key patterns across all file types |
| Supply Chain Vulnerabilities | LLM03 | π΄ Out of scope | Requires dependency analysis |
| Data and Model Poisoning | LLM04 | π΄ Out of scope | Requires runtime monitoring |
| Improper Output Handling | LLM05 | π‘ Partial | eval/exec/shell/SQL/HTML sinks with taint tracking |
| Insecure Plugin Design | LLM06 | π‘ Partial | @tool functions with dangerous sinks |
| System Prompt Leakage | LLM07 | π‘ Partial | Hardcoded prompts in source code and config files |
| Excessive Agency | LLM08 | π’ Strong | 8 pattern categories including dynamic dispatch |
| Misinformation | LLM09 | π΄ Out of scope | Requires runtime factual verification |
| Unbounded Consumption | LLM10 | π‘ Partial | Missing max_tokens on LLM API calls |
Coverage levels
Section titled βCoverage levelsβ- π’ Strong β dual-layer detection (regex + AST taint analysis), multiple pattern categories, high confidence
- π‘ Partial β single-layer detection or limited pattern coverage; PRs welcome to expand
- π΄ Out of scope β not detectable by static analysis alone
What Each Rule Detects
Section titled βWhat Each Rule DetectsβLLM01 β Prompt Injection
- Regex: direct interpolation via f-strings,
.format(),%-formatting, and string concatenation - AST: source-based taint tracking β a variable is tainted only when assigned from a
user-controlled data source (HTTP requests,
input(),sys.argv, WebSocket messages, or function parameters) - Role-aware dict analysis: distinguishes the safe
role: userpattern from dangerousrole: system/role: assistantinjection str.join()injection detection for tainted list elements- Taint propagates through direct alias assignments but not through function calls
LLM02 β Sensitive Info Disclosure
- All file types: OpenAI (
sk-), Anthropic (sk-ant-), Google (AIza), HuggingFace (hf_) patterns - Minimum key length enforcement (20+ chars) to avoid matching SKUs and short placeholders
- Comment lines, test/mock variable names, and example values are skipped
LLM05 β Improper Output Handling
- Regex: detects LLM output variables (by name heuristic: requires both an LLM-context indicator
such as
llm,gpt,ai,chatAND a response indicator such asresponse,output,text,content) passed to dangerous sinks - AST: taint-tracked detection β flags any tainted variable (from any user-controlled source) passed to dangerous sinks without the name-heuristic requirement
@tool-decorated function parameters are treated as LLM output β the LLM chooses their values at runtime, so sinks inside@toolbodies are flagged automatically- Dangerous sinks:
eval(),exec(),compile()β CRITICAL;subprocess.run(),os.system()β CRITICAL;Markup(),render_template_string(),mark_safe()β HIGH; SQL f-string interpolation β HIGH;json.loads()without schema validation β INFO (normal) / MEDIUM (strict)
LLM07 β System Prompt Leakage
- Python: single-line + multi-line hardcoded system prompt strings (> 100 chars)
- Config files: prompt values in
system_prompt:,system_message:,prompt:keys - Only flags strings longer than 100 characters to avoid noise from short generic prompts
LLM08 β Excessive Agency
globals()[fn_name]()/eval(fn_name)β dynamic dispatch from LLM tool call β CRITICALtools=["*"]β wildcard tool access violating least privilege β HIGHShellTool(),PythonREPLTool(),CodeInterpreterTool()β shell/code execution capability β HIGHsubprocess.run(['powershell'/'bash'/'cmd'/'sh', ...])β shell interpreter invocation β HIGH@tool-decorated functions containing shell/subprocess sinks β AST-detected β HIGHgetattr(module, llm_name)()β AST-taint-tracked dynamic dispatch β CRITICAL (AST) / HIGH (regex)auto_approve=True,human_in_the_loop=Falseβ disabled approval gates β MEDIUMFileManagementToolkit(),WriteFileTool()β broad filesystem access β LOW- Broad tool descriptions, missing explicit allowlists β INFO (normal) / MEDIUM (strict)
LLM10 β Unbounded Consumption
- Regex: LLM API calls (openai, anthropic, litellm, Google Gemini) without
max_tokens - AST: resolves
**configdict spreads β suppresses the finding whenmax_tokensormax_output_tokensis provably present in the spread dict