T09 · Insecure Skill Coding Practices
- Location
log_processor.py:12- Finding
Shell Command Injection Through the Container Name
- Content
View full analysis
Vulnerability Details
File Location:
log_processor.py, lines 12-13
Vulnerability Type: OS command injection through unsafe shell invocation
Risk Level: HighVulnerable Code
python cmd = f"docker logs --tail {max_lines} {container_name}" result = subprocess.run(cmd, shell=True, capture_output=True, text=True)The untrusted value originates from the positional command-line argument:
python parser = argparse.ArgumentParser() parser.add_argument("container") args = parser.parse_args() print(process_logs(args.container))Technical Analysis
The user-controlled
container_namevalue is interpolated directly into a shell command. The command is then executed usingsubprocess.runwithshell=True, causing shell metacharacters in the container name to be interpreted as command syntax rather than as part of a single Docker argument.No quoting, validation, or argument separation prevents values containing operators such as semicolons, command substitutions, pipes, or redirections from changing the executed command. This allows a crafted container argument to execute additional operating-system commands.
Attack Path
- An attacker supplies a malicious value where a Docker container name is expected, such as a valid-looking name followed by a shell command separator and another command.
- Following
SKILL.md, the Agent invokeslog_processor.pywith that value as its positional argument. - The script interpolates the complete value into the
docker logscommand. subprocess.run(..., shell=True)passes the resulting string to the system shell.- The shell executes both the intended Docker command and the attacker-injected command.
- The injected command runs with the operating-system privileges and environment of the user or Agent process executing the Skill.
Impact Assessment
Successful exploitation permits arbitrary local command execution with the ...[truncated 493 chars]
- Remediation
View remediation
Remediation Suggestions
Do not invoke a shell. Pass the command and each argument as a separate list element:
python result = subprocess.run( ["docker", "logs", "--tail", str(max_lines), container_name], shell=False, capture_output=True, text=True, check=False, )Apply defense in depth by validating that
container_nameis a valid Docker container name or identifier before execution. Reject unexpected characters rather than attempting to escape them. Themax_linesandcontext_sizeparameters should also be constrained to reasonable integer ranges if they later become user-configurable.Check
result.returncodeand return a controlled diagnostic when Docker rejects the request. Run the Skill under a minimally privileged account and avoid exposing a privileged Docker socket unless it is strictly required.
