Summary
Static analysis (Snyk SAST) identified four instances of command injection vulnerabilities (CWE-78) where unsanitized external input flows into subprocess.Popen or subprocess.call without adequate validation.
Affected Files
1. st2reactor/st2reactor/container/process_container.py (line 361)
This is the most significant finding as it is in core StackStorm infrastructure. The _get_args_for_wrapper_script method at line 499 passes sys.argv[1:] via json.dumps into the argument list that is later executed via subprocess.Popen at line 361. While shell=False mitigates direct shell injection, the unsanitized propagation of CLI arguments into subprocess calls can still be exploited depending on how the downstream wrapper script parses these arguments.
# Line 499
parent_args = json.dumps(sys.argv[1:])
# ...
args = [
python_binary,
self._wrapper_script_path,
"--parent-args=%s" % (parent_args),
]
# ...
# Line 361
process = subprocess.Popen(
args=args,
stdin=None, stdout=None, stderr=None,
shell=False,
env=env,
preexec_fn=on_parent_exit("SIGTERM"),
)
2. contrib/examples/actions/ubuntu_pkg_info/ubuntu_pkg_info.py (line 27)
CLI arguments flow directly into shlex.split and then into subprocess.Popen. While shlex.split provides some parsing, it does not sanitize against injection of additional apt-cache flags or arguments.
command_list = shlex.split("apt-cache policy " + " ".join(args[1:]))
process = subprocess.Popen(
command_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
3. contrib/linux/actions/service.py (line 65)
CLI arguments from sys.argv are passed through quote_unix but then interpolated into file path checks and command arguments. The subprocess.call at line 77 uses shell=False but the path construction at line 64 could allow path traversal.
args = {"act": quote_unix(sys.argv[1]), "service": quote_unix(sys.argv[2])}
# ...
cmd_args = ["/etc/init.d/%s" % (args["service"]), args["act"]]
# ...
subprocess.call(cmd_args, shell=False)
4. packaging/build_st2_venv.py (line 59)
The PEX environment variable and sys.argv[0] flow unsanitized into a subprocess call. An attacker who controls the PEX environment variable can cause execution of an arbitrary binary.
def get_pex_path() -> str:
return os.environ.get("PEX", sys.argv[0])
def unpack_venv(st2_venv_path: Path) -> int:
cmd = [
get_pex_path(), # unsanitized env var
"venv",
"--force",
# ...
]
Impact
- process_container.py: Core infrastructure — could affect any StackStorm deployment running sensors.
- contrib examples/linux actions: Lower risk as contrib code, but users often deploy examples as-is.
- build_st2_venv.py: Build/packaging tooling — exploitable if the build environment is compromised.
Recommended Fix
- Validate and sanitize all external input (CLI arguments, environment variables) before passing to subprocess calls.
- For
process_container.py, validate sys.argv contents against expected argument patterns before propagation.
- For
build_st2_venv.py, validate the PEX environment variable points to an expected path.
- For contrib actions, add input validation for package names and service names (allowlist of characters).
References
- CWE-78: Improper Neutralization of Special Elements used in an OS Command
- Detected by: Snyk Code (SAST)
Summary
Static analysis (Snyk SAST) identified four instances of command injection vulnerabilities (CWE-78) where unsanitized external input flows into
subprocess.Popenorsubprocess.callwithout adequate validation.Affected Files
1.
st2reactor/st2reactor/container/process_container.py(line 361)This is the most significant finding as it is in core StackStorm infrastructure. The
_get_args_for_wrapper_scriptmethod at line 499 passessys.argv[1:]viajson.dumpsinto the argument list that is later executed viasubprocess.Popenat line 361. Whileshell=Falsemitigates direct shell injection, the unsanitized propagation of CLI arguments into subprocess calls can still be exploited depending on how the downstream wrapper script parses these arguments.2.
contrib/examples/actions/ubuntu_pkg_info/ubuntu_pkg_info.py(line 27)CLI arguments flow directly into
shlex.splitand then intosubprocess.Popen. Whileshlex.splitprovides some parsing, it does not sanitize against injection of additionalapt-cacheflags or arguments.3.
contrib/linux/actions/service.py(line 65)CLI arguments from
sys.argvare passed throughquote_unixbut then interpolated into file path checks and command arguments. Thesubprocess.callat line 77 usesshell=Falsebut the path construction at line 64 could allow path traversal.4.
packaging/build_st2_venv.py(line 59)The
PEXenvironment variable andsys.argv[0]flow unsanitized into a subprocess call. An attacker who controls thePEXenvironment variable can cause execution of an arbitrary binary.Impact
Recommended Fix
process_container.py, validatesys.argvcontents against expected argument patterns before propagation.build_st2_venv.py, validate thePEXenvironment variable points to an expected path.References