T09 · Insecure Skill Coding Practices
Error
- Location
- agent_republic.sh:60
- Finding
- User-Controlled Ranking Value Executed as a Shell Command<![CDATA[ ## Vulnerability Details **File Location**: `agent_republic.sh:60-66` **Vulnerability Type**: Command injection caused by incorrect heredoc argument placement **Risk Level**: High ### Vulnerable Code ```bash ranking_json=$(python3 - << PY import json, sys ids = [x.strip() for x in sys.argv[1].split(',') if x.strip()] print(json.dumps({"ranking": ids})) PY "$ranking_csv") ``` ### Technical Analysis The heredoc terminator ends the `python3` command before `"$ranking_csv"` is supplied. Therefore, Python is invoked without the expected `sys.argv[1]`, and Bash interprets the expanded `ranking_csv` value as a separate command inside the command substitution. Shell metacharacters embedded in the value are not reparsed because the expansion is quoted. Nevertheless, a value that identifies an executable path or a command available through `PATH` can be invoked directly. This also makes the normal voting operation unreliable because the Python process attempts to access a missing argument. The vulnerable value originates from the second argument to the `vote` command: ```bash cmd_vote "$1" "$2" ``` ### Attack Path 1. An attacker causes a user or automation system to invoke the voting command with an attacker-selected ranking argument. 2. The supplied ranking value names an executable, for example an attacker-controlled file such as `/tmp/payload`. 3. `cmd_vote` assigns that value to `ranking_csv`. 4. After the Python heredoc terminates, Bash treats `"$ranking_csv"` as another command within the command substitution. 5. The referenced executable runs with the privileges and environment of the user invoking the Skill. Successful exploitation requires the attacker to control or influence the ranking argument and have a suitable executable path or command available on the system. ### Impact Assessment An attacker may execute an existing command or attacker-controlled executable with the invoking user's privileges. The resulting process could access file ...[truncated 385 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Pass the ranking argument to Python before opening the heredoc, and quote the heredoc delimiter: ```bash ranking_json=$(python3 - "$ranking_csv" <<'PY' import json import sys ids = [value.strip() for value in sys.argv[1].split(",") if value.strip()] print(json.dumps({"ranking": ids})) PY ) ``` Additional hardening should include: 1. Validate each ranking identifier against the exact format accepted by the API, such as a UUID or another documented identifier format. 2. Reject empty rankings and enforce a reasonable maximum number and length of identifiers. 3. Keep user input out of shell command positions. 4. Add automated tests using normal values, executable paths, whitespace, quotes, and shell metacharacters. 5. Run a shell linter such as ShellCheck in continuous integration to identify heredoc and argument-placement errors. ]]>
