T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/check.sh:12
- Finding
- Unescaped User Input in Manually Constructed JSON Payload<![CDATA[ ## Vulnerability Details **File Location**: `scripts/check.sh`, lines 12-13 **Vulnerability Type**: JSON injection and malformed request construction **Risk Level**: Medium ### Vulnerable Code ```bash PAYLOAD=$(printf '{"text":"%s","platform":"%s","keywords":"%s","title":"%s"}' "$TEXT" "$PLATFORM" "$KEYWORDS" "$TITLE") RESPONSE=$(curl -s -X POST "${API_BASE}/check" -H "Content-Type: application/json" -d "$PAYLOAD" --connect-timeout 10 --max-time 15) ``` ### Technical Analysis The script manually interpolates the user-controlled `TEXT`, `PLATFORM`, `KEYWORDS`, and `TITLE` values into a JSON string. It does not apply JSON escaping to quotation marks, backslashes, control characters, or line breaks. Shell quoting prevents these values from being evaluated directly as shell commands, so this issue does not establish local command execution. However, shell quoting does not make the values safe for use inside JSON. A crafted value can terminate its intended JSON string and introduce additional properties or otherwise produce malformed JSON. The resulting payload is transmitted to the documented third-party compliance service at: ```text https://1341839497-2yuxt6z58d.ap-guangzhou.tencentscf.com/check ``` ### Attack Path 1. An attacker supplies ad copy or an option value containing JSON syntax, such as quotation marks and additional property delimiters. 2. The argument parser stores the crafted input in `TEXT`, `PLATFORM`, `KEYWORDS`, or `TITLE`. 3. `printf` embeds the input verbatim into `PAYLOAD`, without JSON encoding. 4. The resulting request body contains malformed JSON or attacker-injected properties. 5. The remote service may reject the request, interpret altered fields, or process data differently from what the local caller intended. 6. The script then consumes the resulting response with `jq`, potentially producing misleading compliance results or terminating because `set -e` is enabled. ### Impact Assessment The confirmed impact is limit ...[truncated 502 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Construct the request body with a JSON-aware encoder instead of string interpolation: ```bash PAYLOAD=$(jq -n \ --arg text "$TEXT" \ --arg platform "$PLATFORM" \ --arg keywords "$KEYWORDS" \ --arg title "$TITLE" \ '{text: $text, platform: $platform, keywords: $keywords, title: $title}') ``` Then submit the encoded payload using explicit failure handling: ```bash RESPONSE=$(curl --fail-with-body --silent --show-error \ -X POST "${API_BASE}/check" \ -H "Content-Type: application/json" \ --data-binary "$PAYLOAD" \ --connect-timeout 10 \ --max-time 15) ``` Additional hardening should include: - Validate `PLATFORM` against a fixed allowlist. - Apply reasonable length limits to all user-controlled fields. - Verify that the response is valid JSON and contains the expected schema before processing it. - Display an explicit error if the remote API returns an unsuccessful status. - Warn users that ad text, titles, and keywords are sent to an external Tencent Cloud endpoint and should not contain confidential campaign information. ]]>
