T09 · Insecure Skill Coding Practices
- Location
SKILL.md:23- Finding
Shell Command Injection Through Unsanitized User-Supplied URL
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 23–29
Vulnerability Type: Shell command injection
Risk Level: HighThe skill directs the agent to replace
{url}with an untrusted URL and execute the resulting shell command:bash ### Step 2 — 發送請求與解析 (Fetch & Parse) 執行以下 `curl` 指令(請將 `{url}` 替換為實際連結): ```bash curl -X POST [https://api.cobalt.tools/api/json](https://api.cobalt.tools/api/json) \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{"url": "{url}"}'Technical Analysis
The
{url}placeholder represents user-controlled input and is embedded directly inside a single-quoted shell argument. Shell quoting does not safely contain an input that can itself include a single quote. A malicious value can terminate the JSON argument and introduce shell separators and additional commands.This vulnerability arises before the request reaches Cobalt: the local shell interprets the constructed command. JSON formatting and
Content-Typeheaders therefore provide no protection against shell metacharacters.The endpoint is additionally represented using Markdown-link syntax:
bash [https://api.cobalt.tools/api/json](https://api.cobalt.tools/api/json)This is not a valid literal URL argument for
curland may cause the documented command to fail. Although this is primarily a correctness issue, it reinforces the need to avoid generating executable shell commands from prose through textual substitution.Attack Path
- An attacker supplies an apparent Instagram URL containing a single quote followed by shell control operators and an additional command.
- The agent follows the skill instruction and replaces
{url}verbatim with the attacker-controlled value. - The single quote in the value closes the
-dargument prematurely. - The shell interprets the remaining input as shell syntax rather than URL data.
- The inject ...[truncated 1300 chars]
- Remediation
View remediation
Remediation Suggestions
-
Do not construct shell commands through placeholder substitution. Use an HTTP client API that accepts the endpoint, headers, and JSON body as distinct structured values without invoking a shell.
-
Parse and validate the submitted URL. Require:
- The
httpsscheme. - An explicitly allowlisted Instagram hostname, such as
instagram.comorwww.instagram.com. - Rejection of embedded credentials, control characters, and malformed URLs.
- A path matching the supported Instagram content types.
- The
-
Serialize the request body with a JSON library. Do not manually concatenate the URL into JSON, because characters such as quotes, backslashes, and control characters require JSON escaping.
-
If command-line
curlis unavoidable, pass arguments without a shell. Invoke it through an argument-array API and provide each argument separately. Generate the body using a JSON serializer. Do not usesh -c,bash -c,eval, or an equivalent command interpreter. -
Correct the endpoint representation. Use the literal endpoint rather than Markdown-link syntax:
text https://api.cobalt.tools/api/json -
Apply least privilege and execution controls. Run the downloader in a restricted environment with limited filesystem access, no unnecessary credentials, constrained outbound networking, and a dedicated download directory.
-
Add negative security tests. Test URLs containing single quotes, double quotes, backslashes, newlines, shell separators, command substitutions, and malformed hostnames, and verify that none are interpreted as executable syntax.
-
