T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:296
- Finding
- Unsafe interpolation of attacker-controlled Telegram messages into JSON<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 296–309 **Vulnerability Type**: JSON injection and unsafe shell word splitting **Risk Level**: Medium ### Vulnerable Code ```bash #!/bin/bash OFFSET=0 while true; do UPDATES=$(curl -s "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getUpdates?offset=$OFFSET&timeout=30") for UPDATE in $(echo "$UPDATES" | jq -c '.result[]'); do UPDATE_ID=$(echo "$UPDATE" | jq '.update_id') CHAT_ID=$(echo "$UPDATE" | jq '.message.chat.id') TEXT=$(echo "$UPDATE" | jq -r '.message.text') if [ "$TEXT" != "null" ]; then curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \ -H "Content-Type: application/json" \ -d "{\"chat_id\": $CHAT_ID, \"text\": \"You said: $TEXT\"}" fi OFFSET=$((UPDATE_ID + 1)) done done ``` ### Technical Analysis The echo-bot example retrieves message text from Telegram and interpolates it directly into a JSON string: ```bash -d "{\"chat_id\": $CHAT_ID, \"text\": \"You said: $TEXT\"}" ``` Although `jq -r` extracts the text value, it does not encode that value for safe insertion into another JSON document. An attacker can send text containing quotation marks, backslashes, control characters, or JSON delimiters. These characters may terminate the intended `text` value, introduce additional JSON properties, or make the request body invalid. For example, text shaped like the following can alter the generated JSON structure: ```text hello", "disable_notification": true, "extra": " ``` The resulting body may contain attacker-influenced properties in addition to the intended message text. Whether a particular injected property is accepted depends on Telegram's API parsing and validation, but malformed payload generation is reliably possible. The loop also uses command substitution: ```bash for UPDATE in $(echo "$UPDATES" | jq -c '.result[]'); do ``` Shell word splitting is applied to the compact JS ...[truncated 2096 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Construct JSON with `jq` rather than interpolating untrusted values into a JSON string. Process updates through a line-preserving loop instead of shell command substitution: ```bash #!/bin/bash OFFSET=0 while true; do UPDATES=$(curl --fail --silent --show-error \ "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getUpdates?offset=$OFFSET&timeout=30") || continue while IFS= read -r UPDATE; do UPDATE_ID=$(jq -r '.update_id' <<<"$UPDATE") CHAT_ID=$(jq -r '.message.chat.id // empty' <<<"$UPDATE") TEXT=$(jq -r '.message.text // empty' <<<"$UPDATE") if [ -n "$CHAT_ID" ] && [ -n "$TEXT" ]; then jq -n \ --argjson chat_id "$CHAT_ID" \ --arg text "You said: $TEXT" \ '{chat_id: $chat_id, text: $text}' | curl --fail --silent --show-error \ -X POST \ "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \ -H "Content-Type: application/json" \ --data-binary @- fi OFFSET=$((UPDATE_ID + 1)) done < <(jq -c '.result[]' <<<"$UPDATES") done ``` Additional hardening measures should include: 1. Validate that `update_id` and `chat.id` have the expected numeric types before using them. 2. Handle updates without a `message` or `message.text` field explicitly. 3. Advance and persist the update offset safely so malformed individual messages do not cause indefinite reprocessing. 4. Check `curl` exit codes and Telegram's JSON-level `ok` response before treating a request as successful. 5. Apply reasonable message-length limits and rate limiting to reduce denial-of-service exposure. 6. Keep the bot token out of logs and process listings where possible, and rotate it if accidental disclosure is suspected. ]]>
