T09 · Insecure Skill Coding Practices
- Location
__init__.py:317- Finding
Arbitrary Command Execution Through Unsanitized MPI Node Input
- Content
View full analysis
Vulnerability Details
File Location:
__init__.py, lines 52–57, 317–325, 329–334, and 479–490
Vulnerability Type: OS command injection
Risk Level: HighVulnerable Code
User-controlled node values are extracted without validation:
python def _parse_nodes(message: str) -> list: """Extract node list from 'nodes=10.0.0.1,10.0.0.2' or 'hosts=a,b'.""" m = re.search(r"(?:nodes?|hosts?)=([^\s]+)", message, re.I) if m: return [n.strip() for n in m.group(1).split(",") if n.strip()] return []The resulting values are interpolated directly into a command string:
python def _run_internode_allreduce(binary: str, mpirun: str, nodes: list, gpus_per_node: int, best_env: dict) -> tuple: """Run all_reduce_perf across multiple nodes via MPI. Returns (bw, raw_output).""" host_str = ",".join(f"{n}:{gpus_per_node}" for n in nodes) total_ranks = len(nodes) * gpus_per_node env_args = " ".join(f"-x {k}={v}" for k, v in best_env.items()) cmd = ( f"{mpirun} -np {total_ranks} -H {host_str} " f"-x NCCL_DEBUG=WARN {env_args} " f"{binary} -b 8M -e 4G -f 2 -g 1 2>&1" ) out = _run_cmd(cmd, timeout=300) return _parse_bandwidth(out), outThe command is then executed through a shell:
python def _run_cmd(cmd: str, timeout: int = 60) -> str: """Run *cmd* via shell, return stdout+stderr stripped; empty string on any failure.""" try: return subprocess.check_output( cmd, shell=True, stderr=subprocess.STDOUT, text=True, timeout=timeout ).strip() except Exception: return ""The vulnerable execution path is reached here:
python peer_nodes = _parse_nodes(message) mpirun = _find_mpirun() binary = _find_binary("all_reduce_perf") if peer_nodes and binary and mpirun: all_nodes = [local_hostname] + [n for n ...[truncated 3030 chars]- Remediation
View remediation
Remediation Suggestions
-
Replace command strings with explicit argument arrays and disable shell interpretation:
python cmd = [ mpirun, "-np", str(total_ranks), "-H", host_str, "-x", "NCCL_DEBUG=WARN", ] for key, value in best_env.items(): cmd.extend(["-x", f"{key}={value}"]) cmd.extend([ binary, "-b", "8M", "-e", "4G", "-f", "2", "-g", "1", ]) result = subprocess.run( cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=300, check=False, ) -
Strictly validate every node before command construction. Accept only valid IPv4 addresses, IPv6 addresses, or hostnames conforming to an explicitly defined policy. Reject shell metacharacters, empty labels, ports, paths, and MPI-specific syntax unless deliberately supported.
-
Use Python's
ipaddressmodule for IP addresses and a restrictive, length-bounded hostname validator for DNS names. -
Avoid building environment-variable assignments into shell text. Use subprocess argument elements for MPI's
-xoptions or the subprocessenvparameter where appropriate. -
Refactor
_run_cmd()to accept only argument sequences and permanently removeshell=True. If shell execution is genuinely required elsewhere, isolate it in a separate function that never receives user-controlled data. -
Add regression tests using inputs containing characters such as
;,|,&, backticks,$(), redirection operators, quotes, newlines, and comment markers. Confirm that malformed nodes are rejected before any subprocess starts. -
Run the Skill as a dedicated, unprivileged account or tightly restricted container. Do not run it as root or recommend broad
--privilegedcontainer access when narrow device mappings and capabilities are sufficient.
-
