RSTR-INJ-005 — Go exec.Command("sh", "-c", ...)
Summary
exec.Command is being invoked with a shell wrapper — sh -c,
bash -c, or cmd /c — so the second argument is interpreted as a
shell line. Any attacker-controlled substring becomes shell syntax.
Go's stdlib already protects you against this by accepting an argv
list; the shell wrapper specifically opts back into the dangerous form.
Severity
High.
Languages
Go.
What rastray flags
exec.Command("sh", "-c", "ls " + path) // ← flagged
exec.Command("bash", "-c", fmt.Sprintf("tar czf - %s", path)) // ← flagged
exec.Command("cmd", "/c", "dir " + path) // ← flagged (Windows)
What rastray deliberately does not flag
exec.Command("ls", path)— argv form, no shell.exec.Command("/usr/bin/curl", "-fsSL", url).
How to fix it
Drop the shell wrapper and pass arguments as separate strings — that is the safe form, no escaping required:
cmd := exec.Command("ls", path)
out, err := cmd.Output()
cmd := exec.Command("tar", "czf", "-", path)
If you genuinely need pipes or redirections, compose them in Go rather
than letting the shell parse the command. io.Pipe plus two
exec.Commands achieves a pipeline cleanly:
r, w := io.Pipe()
tar := exec.Command("tar", "czf", "-", path)
tar.Stdout = w
gpg := exec.Command("gpg", "--encrypt", "-r", recipient)
gpg.Stdin = r
// run both, close w when tar exits