Injection Analysis (OWASP A03:2021)
Analyze source code for injection vulnerabilities where user-supplied data flows
into interpreters without proper validation, sanitization, or parameterization.
This is the most code-scannable OWASP category -- most injection patterns leave
clear syntactic fingerprints in source code.
Supported Flags
Read ../../shared/schemas/flags.md for the full flag specification. This skill
supports all cross-cutting flags. Key behaviors:
| Flag |
Injection-Specific Behavior |
--scope |
Default changed. Injection analysis focuses on files containing database queries, system calls, LDAP operations, and eval constructs. |
--depth quick |
Scanners + Grep patterns only, no data-flow tracing. |
--depth standard |
Full code read of scoped files, local data-flow analysis within each file. |
--depth deep |
Trace user input from HTTP entry points through call chains to sinks. Cross-file taint analysis. |
--depth expert |
Deep + red team simulation: craft proof-of-concept payloads, DREAD scoring. |
--severity |
Filter output. Injection findings are typically critical or high. |
--fix |
Generate parameterized replacements for each finding. |
Framework Context
OWASP A03:2021 - Injection
User-supplied data is not validated, filtered, or sanitized by the application.
Dynamic queries or commands are constructed using string concatenation or
interpolation with hostile data. Common injection types:
- SQL Injection (CWE-89): Unsanitized input in SQL queries
- NoSQL Injection (CWE-943): Unsanitized input in MongoDB/NoSQL queries
- OS Command Injection (CWE-78): User input passed to system shell commands
- LDAP Injection (CWE-90): Unsanitized input in LDAP queries
- Expression Language Injection (CWE-917): User input in EL/template engines
- ORM Injection (CWE-89): Raw queries or unsafe ORM usage with user input
STRIDE Mapping: Tampering, Information Disclosure, Elevation of Privilege
Detection Patterns
Read references/detection-patterns.md for the full pattern catalog with
language-specific examples, regex heuristics, and false positive guidance.
Pattern Summary:
- String concatenation in SQL queries
- Template string / f-string SQL construction
- Raw ORM queries with user input
os.system / exec / subprocess with user input
eval() / Function() with user input
- LDAP query string construction with user input
Workflow
Step 1: Determine Scope
- Parse
--scope flag (default: changed).
- Resolve to a concrete file list.
- Filter to relevant file types:
.py, .js, .ts, .jsx, .tsx, .java,
.go, .rb, .php, .cs, .rs, .kt, .scala, .sql, .graphql.
- Prioritize files containing: database query patterns, HTTP handler functions,
system call imports, LDAP library usage, eval/exec constructs.
Step 2: Check for Scanners
Detect available scanners in priority order:
| Scanner |
Detect |
Injection Coverage |
| semgrep |
which semgrep |
SQL, NoSQL, OS command, LDAP, EL, ORM -- broadest coverage |
| bandit |
which bandit |
Python: eval, exec, SQL, subprocess, pickle |
| gosec |
which gosec |
Go: SQL injection, command injection |
| brakeman |
which brakeman |
Rails: SQL injection, command injection, mass assignment |
| spotbugs |
Maven/Gradle plugin |
Java: SQL injection, command injection, XXE, LDAP |
Record which scanners are available and which are missing. If none are available,
note: "No scanner available -- findings based on code pattern analysis only."
Step 3: Run Scanners
For each available scanner, run against the scoped files:
semgrep scan --config auto --json --quiet <target>
bandit -r <target> -f json -q
gosec -fmt json ./...
Normalize scanner output to the findings schema (see ../../shared/schemas/findings.md).
Use the severity mapping from ../../shared/schemas/scanners.md.
Step 4: Claude Analysis
Read each scoped file and analyze for injection patterns not caught by scanners:
- Identify sinks: Database query functions, system calls, LDAP operations,
eval/exec, template engines.
- Trace sources: HTTP request parameters, form data, URL path segments,
headers, cookies, file uploads, environment variables from user input.
- Check sanitization: Is there parameterization, input validation,
allowlisting, or escaping between source and sink?
- Assess context: Is the code reachable from an external entry point?
Is there framework-level protection (e.g., Django ORM, prepared statements)?
- Deduplicate: Merge Claude findings with scanner findings. If both found
the same issue, keep the scanner finding and add Claude's context.
At --depth deep or --depth expert, trace data flow across files:
- Follow function calls from HTTP handlers to database/system call sites.
- Check middleware and interceptors for global sanitization.
- Map the full taint path: source -> transforms -> sink.
Step 5: Report
Output findings using the format from ../../shared/schemas/findings.md.
Each finding must include:
- id:
INJ-001, INJ-002, etc.
- title: Concise description of the injection type and location.
- severity: Based on exploitability, authentication requirements, and impact.
- location: File, line, function, and vulnerable code snippet.
- description: What is vulnerable and why.
- impact: What an attacker can achieve.
- fix: Parameterized/safe replacement code.
- references: CWE, OWASP A03:2021, STRIDE mapping.
What to Look For
These are the primary injection patterns to detect. Each has detailed examples
and regex heuristics in references/detection-patterns.md.
- String concatenation in SQL:
"SELECT * FROM users WHERE id = " + userId
- Template literals in SQL:
`SELECT * FROM users WHERE id = ${userId}`
- F-strings / format strings in SQL:
f"SELECT * FROM users WHERE id = {user_id}"
- Raw ORM queries:
Model.objects.raw(user_input), sequelize.query(userInput)
- OS command construction:
os.system("ping " + host), exec("ls " + dir)
- subprocess with shell=True:
subprocess.call(cmd, shell=True) where cmd includes user input
- eval/exec with user input:
eval(request.body), new Function(userCode)()
- LDAP filter construction:
"(uid=" + username + ")" without escaping
- NoSQL operator injection:
db.users.find({username: req.body.username}) where body can contain $gt, $ne
- Stored procedures with concatenation: Dynamic SQL inside stored procedures
Scanner Integration
Primary: semgrep (broadest injection coverage across languages)
Language-specific: bandit (Python), gosec (Go), brakeman (Rails), spotbugs (Java)
Fallback: Grep regex patterns from references/detection-patterns.md
When scanners are available, run them first and use Claude analysis to:
- Validate scanner findings (reduce false positives).
- Find injection patterns scanners miss (complex data flows, indirect concatenation).
- Provide fix suggestions with parameterized replacements.
When no scanners are available, Claude performs full pattern-based analysis using
the Grep heuristics from references/detection-patterns.md and contextual code
reading. Report these findings with confidence: medium.
Output Format
Use finding ID prefix INJ (e.g., INJ-001, INJ-002).
All findings follow the schema in ../../shared/schemas/findings.md with:
references.owasp: "A03:2021"
references.stride: "T" (Tampering), "I" (Info Disclosure), or "E" (Elevation of Privilege)
metadata.tool: "injection"
metadata.framework: "owasp"
metadata.category: "A03"
CWE Mapping by Injection Type:
| Injection Type |
CWE |
Typical Severity |
| SQL Injection |
CWE-89 |
critical |
| OS Command Injection |
CWE-78 |
critical |
| NoSQL Injection |
CWE-943 |
high |
| LDAP Injection |
CWE-90 |
high |
| Expression Language Injection |
CWE-917 |
high |
| ORM Injection (raw queries) |
CWE-89 |
high |
| eval/exec Injection |
CWE-95 |
critical |
Summary Table
After all findings, output a summary:
| Injection Type | Critical | High | Medium | Low |
|---------------|----------|------|--------|-----|
| SQL | | | | |
| OS Command | | | | |
| NoSQL | | | | |
| eval/exec | | | | |
| LDAP | | | | |
| ORM | | | | |
Followed by: top 3 priorities, scanner coverage notes, and overall assessment.
1---2name: injection3description: This skill should be used when the user asks to "check for injection", "analyze SQL injection", "find injection vulnerabilities", "check for command injection", "find NoSQL injection", "check for LDAP injection", or mentions "injection" in a security context. Maps to OWASP Top 10 2021 A03:2021 - Injection.4---56# Injection Analysis (OWASP A03:2021)78Analyze source code for injection vulnerabilities where user-supplied data flows9into interpreters without proper validation, sanitization, or parameterization.10This is the most code-scannable OWASP category -- most injection patterns leave11clear syntactic fingerprints in source code.1213## Supported Flags1415Read `../../shared/schemas/flags.md` for the full flag specification. This skill16supports all cross-cutting flags. Key behaviors:1718| Flag | Injection-Specific Behavior |19|------|-----------------------------|20| `--scope` | Default `changed`. Injection analysis focuses on files containing database queries, system calls, LDAP operations, and eval constructs. |21| `--depth quick` | Scanners + Grep patterns only, no data-flow tracing. |22| `--depth standard` | Full code read of scoped files, local data-flow analysis within each file. |23| `--depth deep` | Trace user input from HTTP entry points through call chains to sinks. Cross-file taint analysis. |24| `--depth expert` | Deep + red team simulation: craft proof-of-concept payloads, DREAD scoring. |25| `--severity` | Filter output. Injection findings are typically `critical` or `high`. |26| `--fix` | Generate parameterized replacements for each finding. |2728## Framework Context2930**OWASP A03:2021 - Injection**3132User-supplied data is not validated, filtered, or sanitized by the application.33Dynamic queries or commands are constructed using string concatenation or34interpolation with hostile data. Common injection types:3536- **SQL Injection** (CWE-89): Unsanitized input in SQL queries37- **NoSQL Injection** (CWE-943): Unsanitized input in MongoDB/NoSQL queries38- **OS Command Injection** (CWE-78): User input passed to system shell commands39- **LDAP Injection** (CWE-90): Unsanitized input in LDAP queries40- **Expression Language Injection** (CWE-917): User input in EL/template engines41- **ORM Injection** (CWE-89): Raw queries or unsafe ORM usage with user input4243**STRIDE Mapping**: Tampering, Information Disclosure, Elevation of Privilege4445## Detection Patterns4647Read `references/detection-patterns.md` for the full pattern catalog with48language-specific examples, regex heuristics, and false positive guidance.4950**Pattern Summary**:511. String concatenation in SQL queries522. Template string / f-string SQL construction533. Raw ORM queries with user input544. `os.system` / `exec` / `subprocess` with user input555. `eval()` / `Function()` with user input566. LDAP query string construction with user input5758## Workflow5960### Step 1: Determine Scope61621. Parse `--scope` flag (default: `changed`).632. Resolve to a concrete file list.643. Filter to relevant file types: `.py`, `.js`, `.ts`, `.jsx`, `.tsx`, `.java`,65 `.go`, `.rb`, `.php`, `.cs`, `.rs`, `.kt`, `.scala`, `.sql`, `.graphql`.664. Prioritize files containing: database query patterns, HTTP handler functions,67 system call imports, LDAP library usage, eval/exec constructs.6869### Step 2: Check for Scanners7071Detect available scanners in priority order:7273| Scanner | Detect | Injection Coverage |74|---------|--------|--------------------|75| semgrep | `which semgrep` | SQL, NoSQL, OS command, LDAP, EL, ORM -- broadest coverage |76| bandit | `which bandit` | Python: eval, exec, SQL, subprocess, pickle |77| gosec | `which gosec` | Go: SQL injection, command injection |78| brakeman | `which brakeman` | Rails: SQL injection, command injection, mass assignment |79| spotbugs | Maven/Gradle plugin | Java: SQL injection, command injection, XXE, LDAP |8081Record which scanners are available and which are missing. If none are available,82note: "No scanner available -- findings based on code pattern analysis only."8384### Step 3: Run Scanners8586For each available scanner, run against the scoped files:8788```89semgrep scan --config auto --json --quiet <target>90bandit -r <target> -f json -q91gosec -fmt json ./...92```9394Normalize scanner output to the findings schema (see `../../shared/schemas/findings.md`).95Use the severity mapping from `../../shared/schemas/scanners.md`.9697### Step 4: Claude Analysis9899Read each scoped file and analyze for injection patterns not caught by scanners:1001011. **Identify sinks**: Database query functions, system calls, LDAP operations,102 eval/exec, template engines.1032. **Trace sources**: HTTP request parameters, form data, URL path segments,104 headers, cookies, file uploads, environment variables from user input.1053. **Check sanitization**: Is there parameterization, input validation,106 allowlisting, or escaping between source and sink?1074. **Assess context**: Is the code reachable from an external entry point?108 Is there framework-level protection (e.g., Django ORM, prepared statements)?1095. **Deduplicate**: Merge Claude findings with scanner findings. If both found110 the same issue, keep the scanner finding and add Claude's context.111112At `--depth deep` or `--depth expert`, trace data flow across files:113- Follow function calls from HTTP handlers to database/system call sites.114- Check middleware and interceptors for global sanitization.115- Map the full taint path: source -> transforms -> sink.116117### Step 5: Report118119Output findings using the format from `../../shared/schemas/findings.md`.120121Each finding must include:122- **id**: `INJ-001`, `INJ-002`, etc.123- **title**: Concise description of the injection type and location.124- **severity**: Based on exploitability, authentication requirements, and impact.125- **location**: File, line, function, and vulnerable code snippet.126- **description**: What is vulnerable and why.127- **impact**: What an attacker can achieve.128- **fix**: Parameterized/safe replacement code.129- **references**: CWE, OWASP A03:2021, STRIDE mapping.130131## What to Look For132133These are the primary injection patterns to detect. Each has detailed examples134and regex heuristics in `references/detection-patterns.md`.1351361. **String concatenation in SQL**: `"SELECT * FROM users WHERE id = " + userId`1372. **Template literals in SQL**: `` `SELECT * FROM users WHERE id = ${userId}` ``1383. **F-strings / format strings in SQL**: `f"SELECT * FROM users WHERE id = {user_id}"`1394. **Raw ORM queries**: `Model.objects.raw(user_input)`, `sequelize.query(userInput)`1405. **OS command construction**: `os.system("ping " + host)`, `exec("ls " + dir)`1416. **subprocess with shell=True**: `subprocess.call(cmd, shell=True)` where `cmd` includes user input1427. **eval/exec with user input**: `eval(request.body)`, `new Function(userCode)()`1438. **LDAP filter construction**: `"(uid=" + username + ")"` without escaping1449. **NoSQL operator injection**: `db.users.find({username: req.body.username})` where body can contain `$gt`, `$ne`14510. **Stored procedures with concatenation**: Dynamic SQL inside stored procedures146147## Scanner Integration148149**Primary**: semgrep (broadest injection coverage across languages)150**Language-specific**: bandit (Python), gosec (Go), brakeman (Rails), spotbugs (Java)151**Fallback**: Grep regex patterns from `references/detection-patterns.md`152153When scanners are available, run them first and use Claude analysis to:154- Validate scanner findings (reduce false positives).155- Find injection patterns scanners miss (complex data flows, indirect concatenation).156- Provide fix suggestions with parameterized replacements.157158When no scanners are available, Claude performs full pattern-based analysis using159the Grep heuristics from `references/detection-patterns.md` and contextual code160reading. Report these findings with `confidence: medium`.161162## Output Format163164Use finding ID prefix **INJ** (e.g., `INJ-001`, `INJ-002`).165166All findings follow the schema in `../../shared/schemas/findings.md` with:167- `references.owasp`: `"A03:2021"`168- `references.stride`: `"T"` (Tampering), `"I"` (Info Disclosure), or `"E"` (Elevation of Privilege)169- `metadata.tool`: `"injection"`170- `metadata.framework`: `"owasp"`171- `metadata.category`: `"A03"`172173**CWE Mapping by Injection Type**:174175| Injection Type | CWE | Typical Severity |176|---------------|-----|-----------------|177| SQL Injection | CWE-89 | critical |178| OS Command Injection | CWE-78 | critical |179| NoSQL Injection | CWE-943 | high |180| LDAP Injection | CWE-90 | high |181| Expression Language Injection | CWE-917 | high |182| ORM Injection (raw queries) | CWE-89 | high |183| eval/exec Injection | CWE-95 | critical |184185### Summary Table186187After all findings, output a summary:188189```190| Injection Type | Critical | High | Medium | Low |191|---------------|----------|------|--------|-----|192| SQL | | | | |193| OS Command | | | | |194| NoSQL | | | | |195| eval/exec | | | | |196| LDAP | | | | |197| ORM | | | | |198```199200Followed by: top 3 priorities, scanner coverage notes, and overall assessment.