Skip to content
Back to skills

Detecting Command Injection Patterns

ASecurity

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-proc...

  • 2,719 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 21, 2026
ai-agentspythongojavarubyphpshellbashnodegitapi

Works with

  • claude code
  • cli
  • api

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned September 21, 2026

npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill detecting-command-injection-patterns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Detecting Command Injection Patterns?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Detecting Command Injection Patterns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jeremylongshore-detecting-command-injection-patterns-9d1a243f/badge)](https://www.skillsdirectory.com/skills/jeremylongshore-detecting-command-injection-patterns-9d1a243f)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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.md5 KB
  • references/PLAYBOOK.md6.8 KB
  • references/THEORY.md7 KB
  • scripts/scan_cmdi.py8.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.