Detecting Command Injection Patterns
ASecurityScan a source tree for command-injection vulnerable patterns: shell=True calls in Python subprocess, os.system / os.popen with interpolated strings, Node child_process.exec with template literals, Ruby backticks / Kernel#system / Kernel#exec with interpolation, Go exec.Command with shell wrapping, PHP system / passthru / shell_exec / backticks with $-interpolation, Java Runtime.exec with concatenated args. Use when: pre-commit gate on code that calls out to shell utilities, audit of file-proc...
- 2,719 stars
- 0 votes
- 0 copies
- 2 views
- Added September 21, 2026
Works with
Security analysis
100/100Pro scans all 4 files and shows the line behind each finding
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill detecting-command-injection-patterns --agent claude-codeAre you the author of Detecting Command Injection Patterns?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/jeremylongshore-detecting-command-injection-patterns-9d1a243f)---
name: detecting-command-injection-patterns
description: |
Scan a source tree for command-injection vulnerable patterns:
shell=True calls in Python subprocess, os.system / os.popen with
interpolated strings, Node child_process.exec with template
literals, Ruby backticks / Kernel#system / Kernel#exec with
interpolation, Go exec.Command with shell wrapping, PHP system /
passthru / shell_exec / backticks with $-interpolation, Java
Runtime.exec with concatenated args.
Use when: pre-commit gate on code that calls out to shell utilities,
audit of file-processing / archive-handling / image-conversion
code, post-bug-report investigation for "we shell out to a tool."
Threshold: any shell-invocation API called with a string that
contains a variable interpolation, OR shell=True with anything
other than a fixed literal.
Trigger with: "scan command injection", "shell=True audit",
"find exec calls", "check os.system".
allowed-tools:
- Read
- Bash(python3:*)
- Glob
- Grep
disallowed-tools:
- Bash(rm:*)
- Bash(curl:*)
version: 3.30.0
author: Jeremy Longshore <jeremy@intentsolutions.io>
license: MIT
compatibility: Designed for Claude Code
tags:
- security
- static-analysis
- command-injection
- pentest
---
# Detecting Command Injection Patterns
## Overview
Command injection (CWE-78, OWASP A03:2021) shows up wherever an
application shells out to a binary. Image conversion (`convert`),
archive extraction (`tar`, `unzip`), video processing (`ffmpeg`),
DNS lookup (`dig`), and "we just need to call this CLI tool once"
are the common origins.
The vulnerability shape is universal: a string is built including
user input, then handed to a shell interpreter. The shell parses
the string with normal shell semantics — including `;`, `|`, `&`,
`$()`, backticks. Any of those in the user-controlled portion
becomes shell-executable.
## When the skill produces findings
| Finding | Severity | Threshold | Affected control |
|---|---|---|---|
| Python `subprocess.run(..., shell=True)` with interpolation | **CRITICAL** | f-string / concat / format argument with `shell=True` | CWE-78 |
| Python `os.system(...)` with interpolation | **CRITICAL** | non-literal argument | CWE-78 |
| Python `os.popen(...)` with interpolation | **CRITICAL** | non-literal argument | CWE-78 |
| Node `child_process.exec(...)` with template literal | **CRITICAL** | `${...}` in the command string | CWE-78 |
| Node `child_process.execSync(...)` with template | **CRITICAL** | same | CWE-78 |
| Ruby backticks with interpolation | **CRITICAL** | `` `cmd #{var}` `` | CWE-78 |
| Ruby `Kernel#system(string)` with interpolation | **CRITICAL** | `system("cmd #{var}")` | CWE-78 |
| Go `exec.Command("sh", "-c", ...)` with interpolation | **HIGH** | shell wrapper with var | CWE-78 |
| PHP `system / exec / passthru / shell_exec` with $-interp | **CRITICAL** | `system("cmd $var")` | CWE-78 |
| Java `Runtime.exec(String)` with concat | **HIGH** | single-string form (vs array) with var | CWE-78 |
## Prerequisites
- Python 3.9+
- Target source tree on local filesystem
## Instructions
### Step 1 — Run the scanner
```bash
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-command-injection-patterns/scripts/scan_cmdi.py /path/to/repo
```
Options:
```
Usage: scan_cmdi.py PATH [OPTIONS]
Options:
--output FILE Write findings to FILE
--format FMT json | jsonl | markdown (default: markdown)
--min-severity SEV (default: info)
--include-tests Include test directories (default: excluded)
--languages LIST Comma-separated subset to scan
```
### Step 2 — Interpret findings
CRITICAL = direct user-input → shell construction. Fix immediately.
HIGH = pattern where the shell layer exists but user-input reachability
needs verification.
### Step 3 — Remediation
The universal fix: pass arguments as a list (array), not a single
string. Most APIs have a list form that bypasses shell entirely.
See `references/PLAYBOOK.md` for per-language patterns.
## Examples
### Example 1 — Pre-commit on a media-processing service
```bash
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-command-injection-patterns/scripts/scan_cmdi.py \
--min-severity high $(git diff --name-only main...HEAD | tr '\n' ' ')
```
### Example 2 — CI gate
```yaml
- name: Command-injection scan
run: |
python3 plugins/security/penetration-tester/skills/detecting-command-injection-patterns/scripts/scan_cmdi.py \
. --min-severity high
```
## Output
JSON / JSONL / Markdown. Exit codes: 0 clean, 1 high/critical, 2 error.
## Error Handling
False positives common in build scripts that interpolate fixed
build constants. Verify each finding by reading whether the
interpolated value is user-reachable.
## Resources
- `references/THEORY.md` — Why shell=True is the default footgun,
per-language shell-out idioms, argument-vector vs command-string
semantics
- `references/PLAYBOOK.md` — Per-language safe-shellout patterns
(Python subprocess list-args, Node spawn, Ruby Open3.capture3,
Go exec.Command list-args, Java ProcessBuilder, PHP escapeshellarg)
Files in this skill
- SKILL.md
- references/PLAYBOOK.md
- references/THEORY.md
- scripts/scan_cmdi.py
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.