VNX-1037 – Process Injection
Overview
VNX-1037 is an auto-generated broad-pattern rule that searches for OS process execution primitives across Go, Java, Node.js, PHP, Python, and Ruby source files. The rule targets exec.Command in Go, Runtime in Java, child_process in Node.js, shell_exec in PHP, subprocess in Python, and system in Ruby. These are associated with CWE-1037 in the rule metadata.
Note: CWE-1037 in MITRE’s catalog covers “Processor Optimization Removal or Modification of Security-critical Code,” which does not align with the intent of this rule. The rule is functionally a command injection detector, more accurately mapped to CWE-78: Improper Neutralization of Special Elements used in an OS Command and the MITRE ATT&CK technique T1055 (Process Injection).
All flagged locations identify process execution APIs whose use is not inherently unsafe but requires careful validation of any user-controlled input passed as arguments.
Severity: Medium | CWE: CWE-1037 | OWASP: A03:2021 – Injection
Why This Matters
Command injection is consistently among the most critical vulnerability classes because it typically grants an attacker full control over the application host. When user-supplied data — query parameters, form fields, file names, API responses — reaches an OS process execution API without sanitisation, the attacker can execute arbitrary commands with the privileges of the application process.
Many developers believe parameterised argument arrays (e.g., exec.Command("ls", userArg)) are always safe, but shell=True equivalents and string concatenation into command builders remain common mistakes that bypass this protection.
What Gets Flagged
The rule scans Go, Java, Node.js, PHP, Python, and Ruby source files for process execution patterns:
# FLAGGED: Python subprocess with user input
import subprocess
subprocess.run(f"convert {filename}", shell=True)
// FLAGGED: Node.js child_process
const { exec } = require('child_process');
exec(`git log ${userBranch}`, callback);
// FLAGGED: Go exec.Command
cmd := exec.Command("bash", "-c", userInput)
cmd.Run()
Remediation
- Avoid shell interpolation entirely. Pass arguments as discrete array elements rather than building shell command strings.
- In Python, use
subprocess.run([cmd, arg1, arg2], shell=False)— never setshell=Truewith untrusted input. - In Go, pass each argument separately to
exec.Command("program", arg1, arg2)rather than concatenating into a single string. - Validate and allowlist any user-controlled values that must be passed to subprocess calls.
- Run application processes under a dedicated low-privilege account to limit the impact of exploitation.