T09 · Insecure Skill Coding Practices
- Location
SKILL.md:126- Finding
Potential Command Injection Through Unescaped Search Query
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, line 126
Vulnerability Type: OS command injection caused by unsafe command construction
Risk Level: HighVulnerable Code
markdown **Step Q1**:执行 `qmd search "<query>" -n 5 --json`(本机环境 `qmd query` 的 LLM 扩充会超时,故用 search 替代)Technical Analysis
The skill instructs the agent to insert a direct user query into a shell-style command. Although the placeholder is enclosed in double quotes, the document does not require shell-free execution, argument-array invocation, validation, or escaping.
If an implementing agent substitutes untrusted input into this command and invokes it through a command shell, a query containing a double quote and shell control operators could terminate the intended argument and introduce an additional command. Quoting alone is not a sufficient defense because shell parsing occurs before
qmdreceives its arguments.The project contains only
SKILL.md; therefore, no concrete execution wrapper is available to determine whether the command is ultimately passed through a shell. The finding applies to implementations that follow this instruction using shell interpolation.Attack Path
- An attacker submits a direct knowledge-base question containing a closing quote, shell control syntax, and an unintended command.
- The skill selects the QUERY workflow and substitutes the attacker-controlled text for
<query>. - An agent or integration constructs the documented command as a single shell command string.
- The shell treats the injected syntax as executable command structure rather than as part of the search term.
- The injected command executes with the operating-system privileges and filesystem access of the agent process.
Impact Assessment
Successful exploitation could permit arbitrary local command execution under the agent's account. The attacker could potentially read files accessible to that acc ...[truncated 467 chars]
- Remediation
View remediation
Remediation Suggestions
- Invoke
qmdthrough a structured process API with a fixed executable and argument array, for example:text ["qmd", "search", query, "-n", "5", "--json"] - Disable shell evaluation explicitly; do not construct a single command string or use shell invocation options such as
shell=true. - Treat the complete question as opaque data passed in one argument.
- If the available tool accepts only command strings, use a platform-appropriate, well-tested escaping library rather than manual quoting.
- Reject control characters and enforce a reasonable maximum query length as defense-in-depth measures.
- Update the skill instruction to state that user input must never be interpreted as shell syntax.
- Add tests using embedded quotes, command separators, command substitutions, redirection operators, and newline characters to verify that all such values reach
qmdonly as literal search text.
- Invoke
