T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/docker_analyzer.sh:113
- Finding
- Arbitrary Python Code Execution Through Unsafely Interpolated Image Name## Vulnerability Details **File Location**: `scripts/docker_analyzer.sh`, lines 113–116 **Vulnerability Type**: Python code injection through an unquoted shell heredoc **Risk Level**: High ### Vulnerable Code ```bash python3 << PYEOF import subprocess, json image = "$image" try: ``` ### Technical Analysis The `optimize` command reads an image name from its first command-line argument and stores it in the shell variable `image`. It then uses an unquoted heredoc delimiter (`PYEOF`) to construct a Python program. Because the delimiter is unquoted, Bash performs parameter expansion within the heredoc before passing its contents to Python. The attacker-controlled value of `$image` is therefore inserted directly into Python source code inside a double-quoted string. An image argument containing a double quote can terminate that string and append arbitrary Python statements. A payload with the following structure demonstrates the injection primitive: ```text "; __import__("os").system("malicious-command"); # ``` After shell expansion, Python interprets the injected expression as executable source code. Execution occurs before the subsequent Docker operation can validate whether the supplied value is a legitimate image reference. The use of a list-form argument in the later `subprocess.check_output` call does not mitigate this earlier source-code injection. ### Attack Path 1. An attacker gains the ability to control or influence the image argument supplied to `docker-analyzer optimize`. 2. The script assigns that argument to the `image` shell variable. 3. Bash expands `$image` while processing the unquoted heredoc. 4. A crafted quote terminates the intended Python string and introduces attacker-selected Python statements. 5. The Python interpreter parses and executes those statements with the privileges of the Docker Analyzer process. 6. The injected code can invoke operating-system commands, read accessible fi ...[truncated 915 chars]
- Remediation
- ## Remediation Suggestions Do not interpolate shell-controlled data into generated Python source. Pass the image name as a positional argument and quote the heredoc delimiter so that Bash performs no expansion: ```bash python3 - "$image" <<'PYEOF' import json import subprocess import sys image = sys.argv[1] try: out = subprocess.check_output( [ "docker", "history", "--no-trunc", "--format", "{{json .}}", image, ], stderr=subprocess.STDOUT, ).decode() # Continue processing the result. except Exception as exc: print("Error: {}".format(exc)) PYEOF ``` Additional hardening measures: 1. Preserve list-form subprocess invocation and never use `shell=True` for the image value. 2. Optionally validate image references against the syntax accepted by Docker as defense in depth, but do not treat validation as a substitute for separating data from code. 3. Add regression tests using image values containing quotes, backslashes, command substitutions, newlines, semicolons, and Python comment characters. 4. Run the analyzer with the least-privileged account possible and avoid unnecessary root or Docker daemon access. 5. Review future heredocs and embedded-language blocks to ensure all delimiters are quoted whenever shell expansion is unnecessary.
