T09 · Insecure Skill Coding Practices
- Location
SKILL.md:23- Finding
Shell Command Injection Through Unsafe User-Controlled Template Substitution
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:23-27,SKILL.md:47-65
Vulnerability Type: Shell command injection and unsafe JSON construction
Risk Level: HighVulnerable Code
bash curl -s -X POST https://sooda.ai/api/v1/signup \ -H "Content-Type: application/json" \ -d '{"email":"USER_EMAIL_HERE"}'bash curl -s -X POST https://sooda.ai/api/v1/relay/AGENT_NAME \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SOODA_API_KEY" \ -H "X-Sooda-Context-ID: CONTEXT_ID_OR_OMIT" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "message/send", "params": { "message": { "role": "user", "parts": [{"type": "text", "text": "USER_MESSAGE_HERE"}] } } }'markdown - Replace `AGENT_NAME` with the target agent (e.g. `travelwise`, `helpdesk`) - Replace `USER_MESSAGE_HERE` with the user's messageTechnical Analysis
The skill directs the executing agent to replace placeholders inside shell command templates with user-controlled email addresses, messages, and agent names. The email and message placeholders occur inside single-quoted shell arguments, but the supplied values are not encoded with a JSON serializer or escaped for the shell.
A single quote in a supplied value can terminate the shell-quoted
-dargument. The remaining input can then introduce shell separators and arbitrary commands. Even without deliberate shell injection, quotation marks, backslashes, newlines, or control characters can produce malformed JSON or alter the request's structure.AGENT_NAMEis also inserted directly into the URL without an enforced allowlist or URL-safe encoding. This permits unintended path or argument manipulation if an implementation performs literal textual substitution.This issue is exploitable when an agent or wrapper follows the documented process by constructing a command string and execu ...[truncated 2196 chars]
- Remediation
View remediation
Remediation Suggestions
-
Do not create executable shell commands by replacing placeholders in command strings.
-
Construct request bodies with a JSON serializer. For example:
bash signup_body="$(jq -n --arg email "$user_email" '{email: $email}')" curl --silent --show-error --fail-with-body \ --request POST \ --url 'https://sooda.ai/api/v1/signup' \ --header 'Content-Type: application/json' \ --data-binary "$signup_body" -
Build relay payloads using the same serialization approach:
bash relay_body="$(jq -n --arg message "$user_message" '{ jsonrpc: "2.0", id: 1, method: "message/send", params: { message: { role: "user", parts: [{type: "text", text: $message}] } } }')" -
Invoke curl with arguments passed separately through a process-execution API. Do not use
eval,sh -c,bash -c, or equivalent execution of a dynamically assembled command string. -
Enforce an exact allowlist for agent names before constructing the endpoint:
text helpdesk travelwise dineout support procurebot vendorbot -
Construct the relay URL only after allowlist validation. Reject values containing slashes, whitespace, control characters, shell metacharacters, or unrecognized identifiers.
-
Validate email length and basic syntax for user feedback, while continuing to rely on JSON serialization rather than validation as the injection defense.
-
Update the skill instructions to require structured argument passing and explicitly prohibit literal interpolation of untrusted values into shell commands.
-
Add tests containing single quotes, double quotes, backslashes, newlines, Unicode, and shell metacharacters to verify that each value remains data and cannot change command structure.
-
