Zennoxa Shield
Rules / Go
SHIELD-GO-007

Command injection via exec.Command with user input

criticalGoCWE-78CVSS 9.8

What it detects

Passing user-controlled data to exec.Command allows command injection.

How to fix

Never pass user input directly to exec.Command. Validate and allowlist commands and arguments.

Vulnerable — Shield flags thisping.go
package netcheck

import (
	"net/http"
	"os/exec"
)

func PingHandler(w http.ResponseWriter, r *http.Request) {
	// A host like "example.com; rm -rf /" runs arbitrary shell commands
	out, _ := exec.Command("sh", "-c", "ping -c 1 "+r.FormValue("host")).CombinedOutput()
	w.Write(out)
}
Fixed — scans cleanping.go
package netcheck

import (
	"net/http"
	"os/exec"
)

// Allowlist: only these named targets can ever be probed.
var probeTargets = map[string]string{
	"db":    "db.internal.example.com",
	"cache": "cache.internal.example.com",
}

func PingHandler(w http.ResponseWriter, r *http.Request) {
	host, ok := probeTargets[r.FormValue("target")]
	if !ok {
		http.Error(w, "unknown target", http.StatusBadRequest)
		return
	}
	out, _ := exec.Command("ping", "-c", "1", host).CombinedOutput()
	w.Write(out)
}

Both snippets are verified against the shipped scanner: the vulnerable one triggers SHIELD-GO-007, the fixed one does not.

SHIELD-GO-007: Command injection via exec.Command with user input — Zennoxa Shield