T09 · Insecure Skill Coding Practices
- Location
SKILL.md:884- Finding
Unsafe interpolation of untrusted email content into an authenticated JSON request
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:884-897
Vulnerability Type: JSON injection through direct shell-variable interpolation
Risk Level: HighVulnerable Code
bash #!/bin/bash # Extract email subject and body SUBJECT="$1" BODY="$2" curl -s "$YATTA_API_URL/tasks" \ -H "Authorization: Bearer $YATTA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "'"$SUBJECT"'", "description": "'"$BODY"'", "priority": "medium", "import_source": "email" }' \ | jq -r '"Task created: \(.title)"'Technical Analysis
The example inserts
SUBJECTandBODYdirectly into a JSON string. Neither value is escaped according to JSON syntax. A value containing quotation marks, commas, braces, or additional properties can terminate the intended string and alter the request object.This contradicts the Skill's earlier assertion that all variable-bearing JSON payloads are built using
jq -n --arg. Shell quoting does not provide JSON escaping. Because the request is authenticated withYATTA_API_KEY, the injected payload is submitted with the user's full Yatta account privileges.For example, an attacker-controlled subject could attempt to close the
titlevalue and inject additional task properties. Even when the resulting payload is rejected, crafted input can reliably corrupt task creation and cause denial of service in email-import workflows.Attack Path
- A user adopts the documented “Create Task from Email” script.
- An attacker sends an email containing crafted JSON syntax in its subject or body.
- The email-processing workflow passes the attacker-controlled values as the script's arguments.
- The script concatenates those values directly into the JSON request body.
- The resulting request contains malformed or attacker-modified fields.
curlsends the payload to the API using the victim's full-access bearer token.- If accepted by the API, a task is created with unintended properties ...[truncated 663 chars]
- Remediation
View remediation
Remediation Suggestions
Construct the entire payload with
jq, passing every untrusted string through--arg:bash #!/bin/bash set -euo pipefail SUBJECT="${1:?Email subject is required}" BODY="${2:?Email body is required}" PAYLOAD=$(jq -n \ --arg title "$SUBJECT" \ --arg description "$BODY" \ --arg priority "medium" \ --arg import_source "email" \ '{ title: $title, description: $description, priority: $priority, import_source: $import_source }') curl --fail-with-body --silent --show-error \ "$YATTA_API_URL/tasks" \ -H "Authorization: Bearer $YATTA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary "$PAYLOAD" \ | jq -r '"Task created: \(.title)"'Also:
- Add automated tests using quotes, backslashes, newlines, braces, and Unicode in both fields.
- Remove the claim that all examples are safe until every example has been reviewed.
- Apply length and schema validation before submitting email-derived content.
- Avoid automatically processing untrusted email into state-changing API calls without explicit user approval.
