T09 · Insecure Skill Coding Practices
- Location
SKILL.md:37- Finding
Shell Command Injection Through Raw User Query Interpolation
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:37-48
Vulnerability Type: Shell command injection
Risk Level: HighVulnerable Code:
markdown ### Step 1: Run the router Execute the routing script with the user's query: ```bash python3 {SKILL_DIR}/skill_radar/cli.py route "{USER_QUERY}" --skills-dir {SKILLS_DIR} --format jsonWhere:
{SKILL_DIR}= the directory where this skill (skill-radar) is installed{SKILLS_DIR}= the directory containing all other skills (each with arouting.yaml){USER_QUERY}= the user's raw input text
text ### Technical Analysis The self-routing protocol instructs the agent to interpolate the user's raw input into a shell command. Double quotes do not neutralize every shell metacharacter. In particular, command substitution expressions such as `$(command)` and backtick substitutions remain active inside double-quoted shell arguments. Consequently, if an agent follows this documented command by constructing and executing a shell command string, a malicious query can cause the shell to execute attacker-selected commands before the routing CLI receives the query. The Python CLI does not independently invoke a shell, so exploitation depends on the host agent implementing this instruction through a shell command string. Nevertheless, the affected integration mode explicitly directs shell-capable agents to perform this interpolation and defines `{USER_QUERY}` as unmodified raw input. ### Attack Path 1. Skill Radar is active in self-routing mode. 2. An attacker submits a query containing shell command substitution, for example a query containing `$(id)`. 3. The agent substitutes the raw query into the documented command template. 4. The agent executes the resulting text through a shell. 5. The shell evaluates the embedded command substitution before launching Python. 6. The injected command executes with the operating-system privileges and envi ...[truncated 881 chars]- Remediation
View remediation
Remediation Suggestions
-
Do not construct a shell command by interpolating user-controlled text.
-
Invoke the CLI through an argument-array API with shell processing disabled. For example:
python subprocess.run( [ sys.executable, str(skill_dir / "skill_radar" / "cli.py"), "route", user_query, "--skills-dir", str(skills_dir), "--format", "json", ], shell=False, check=True, text=True, capture_output=True, ) -
Prefer passing the query through standard input or a structured JSON input channel rather than embedding it in a command line.
-
Revise
SKILL.mdto explicitly prohibitshell=True, string-based command construction, and direct interpolation of raw user input. -
If a particular framework only accepts shell text, use a trusted platform-specific argument-escaping function. Manual quoting with double quotes is insufficient.
-
Apply the same safe handling to
{SKILL_DIR}and{SKILLS_DIR}, since paths may also contain shell-sensitive characters. -
Add integration tests containing command substitutions, quotes, semicolons, newlines, and other shell metacharacters to verify that they are passed to the router literally.
-
