Skip to main content
Founding Partner + 7-Day Trial
Tier B Enterprise Fleet · 12-Language Immunity EngineAutoExtinguish: true (4-Gate Vericoding)

AutoExtinguish: true across all 12 supported languages for single-command invocations convertible to discrete shell-free argv arrays.

Commercial boundary: ciphermap immunity scan, immunity extinguish --apply, immunity attest (CycloneDX 1.6 CISA IBOM & OpenVEX 0.2.0), and ciphermap mcp require Tier B Enterprise Fleet. Offline proof and IBOM verification (--verify-proof, attest --verify) and the ciphermap demo sandbox run Free.

Back to docs
IMM-CMD-001CRITICALCISA Secure-by-Design Pledge · CWE-78 · NIST SP 800-53 Rev. 5 (SI-10)

Dynamic Shell Command Execution Across Polyglot Process APIs

Severity: CRITICAL

Invoking a command shell (sh -c, bash -c, cmd.exe /c, system(), popen(), backticks, or single-string process spawners) with dynamically constructed strings exposes the process to OS command injection via shell metacharacters (;, |, &&, $(), backticks). Invoke the target binary directly with discrete argv elements and shell execution disabled across Go, TypeScript, JavaScript, Python, Java, Kotlin, C#, Rust, C/C++, Ruby, PHP, and Swift.

Remediation checklist

  • Go: invoke exec.CommandContext(ctx, binary, arg1, arg2, ...) directly without sh -c; TypeScript & JavaScript: use child_process.execFile / execFileSync(binary, args, { shell: false }) instead of exec/execSync.
  • Python: call subprocess.run([binary, *args], shell=False, check=True) instead of os.system or shell=True; Java & Kotlin: pass discrete List/vararg elements to ProcessBuilder(binary, arg1, ...) instead of Runtime.exec(cmd) or sh -c.
  • C#: configure ProcessStartInfo with UseShellExecute = false and populate ArgumentList; Rust: use std::process::Command::new(binary).args([...]) without routing through sh -c; C/C++: use posix_spawnp or execve with discrete argv[] instead of system()/popen().
  • Ruby: pass multiple discrete string arguments to system(binary, *args) or Open3.capture2e(binary, *args) instead of interpolated single strings or backticks; PHP: pass a PHP 7.4+ argv array to proc_open([$binary, $arg], ...) or Symfony new Process([$binary, $arg]); Swift: set Foundation.Process.executableURL directly to the target binary with discrete arguments.
  • Precede positional operands with '--' on flag-accepting tools (git, tar, ssh, grep) so untrusted values starting with '-' cannot inject option flags.

Illustrative Code Examples

These fragments explain migration direction. They are not complete applications or compiler-verified patches for your project.

Vulnerable — shell-mediated command execution (Go / Ruby / PHP)

terminal · zsh
// Go: shell interpreter with dynamic command
out, err := exec.CommandContext(ctx, "sh", "-c", "git show "+rev).CombinedOutput()

# Ruby: single-string system() invokes /bin/sh
system("convert #{input_path} #{output_path}")

// PHP: shell_exec invokes /bin/sh -c
$out = shell_exec("whois " . $domain);

Remediated — shell-free discrete argv array + '--' option terminator

terminal · zsh
// Go: direct execve argv array + '--' option terminator
if strings.HasPrefix(rev, "-") { return nil, fmt.Errorf("invalid rev") }
out, err := exec.CommandContext(ctx, "git", "show", rev, "--").CombinedOutput()

# Ruby: multi-argument system() bypasses /bin/sh
system("convert", "--", input_path, output_path)

// PHP: array-form proc_open bypasses the shell
$proc = proc_open(['whois', '--', $domain], [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes);

Preview remediation proposals

Preview proposed changes free with ciphermap fix . --dry-run --offline --no-telemetry. Eligibility depends on the installed build, call shape, module format, and migration context. The bundled RSA fixture has a classical key-size candidate; that does not make it post-quantum secure. Persisted digests and unsupported contexts may be declined. Applying supported candidates requires an entitlement, explicit verifier consent, and the required project tools. Review the actual verification result before adopting a change.

View DevSecOps pricing

Other rule families