48 / 70 · 07 Security Testing for AI Apps · SAST, DAST, and SCA in CI: Shift-Left Security Pipeline← prev⊞ allnext →☰ Read as one page
8.4AI-Specific Semgrep Rules
Standard SAST rules do not catch AI-specific vulnerabilities. Write custom Semgrep rules:
# .semgrep/ai-security-rules.yaml
rules:
- id: llm-output-used-in-sql
pattern: |
$QUERY = f"... {$LLM_RESPONSE} ..."
$DB.execute($QUERY)
message: "LLM output used directly in SQL query. Use parameterized queries."
severity: ERROR
languages: [python]
metadata:
category: security
owasp: "A03:Injection"
ai_specific: true
- id: llm-output-used-in-shell
patterns:
- pattern: os.system(f"... {$LLM_RESPONSE} ...")
- pattern: subprocess.run(f"... {$LLM_RESPONSE} ...", shell=True)
message: "LLM output used in shell command. Sanitize or use allowlist."
severity: ERROR
languages: [python]
metadata:
category: security
owasp: "A03:Injection"
- id: api-key-in-prompt
pattern: |
$PROMPT = f"... $API_KEY ..."
message: "API key may be included in LLM prompt. Remove sensitive data."
severity: WARNING
languages: [python]
- id: no-output-sanitization
pattern: |
$RESPONSE = $LLM.generate(...)
return $RESPONSE
message: "LLM output returned without sanitization. Add output validation."
severity: WARNING
languages: [python]
- id: no-max-tokens-set
pattern: |
$CLIENT.chat.completions.create(
...,
~max_tokens,
...
)
message: "LLM call without max_tokens. Set a limit to prevent cost/DoS issues."
severity: WARNING
languages: [python]
- id: hardcoded-llm-api-key
patterns:
- pattern: '"sk-..."'
- pattern: "'sk-...'"
- pattern: |
$KEY = "sk-$REST"
message: "Hardcoded OpenAI API key detected. Use environment variables."
severity: ERROR
languages: [python, javascript, typescript]