T09 · Insecure Skill Coding Practices
Warning
- Location
- solve-recaptcha.sh:25
- Finding
- Unescaped Arguments Permit CapMonster JSON Request Manipulation<![CDATA[ ## Vulnerability Details **File Location**: `solve-recaptcha.sh`, lines 25–34 **Vulnerability Type**: Improper construction of a JSON request using untrusted input **Risk Level**: Medium ### Vulnerable Code ```bash RESPONSE=$(curl -s -X POST https://api.capmonster.cloud/createTask \ -H "Content-Type: application/json" \ -d "{ \"clientKey\": \"$API_KEY\", \"task\": { \"type\": \"RecaptchaV2TaskProxyless\", \"websiteURL\": \"$WEBSITE_URL\", \"websiteKey\": \"$SITEKEY\" } }") ``` ### Technical Analysis The script directly interpolates `CAPMONSTER_API_KEY`, `WEBSITE_URL`, and `SITEKEY` into a JSON string without applying JSON escaping or validating their format. `WEBSITE_URL` and `SITEKEY` may originate from a webpage inspected by browser automation. A malicious or compromised page can therefore supply values containing quotation marks, backslashes, commas, or JSON delimiters. Such input can terminate the intended JSON string and insert, replace, or duplicate request properties. This is JSON request-body injection rather than shell command injection. The variables remain inside a quoted shell argument, so shell metacharacters in these values are not evaluated as separate commands. Nevertheless, the structure and meaning of the request sent to CapMonster can be altered. Whether duplicate or unexpected properties are accepted depends on the remote API parser and schema validation. The script also fails to verify that `CAPMONSTER_API_KEY` is non-empty and does not restrict `WEBSITE_URL` to an expected `http` or `https` URL. ### Attack Path 1. An attacker controls or compromises a page processed by the browser automation. 2. The page exposes an attacker-crafted CAPTCHA site key or URL containing JSON syntax. 3. The automation extracts that value and passes it to `solve-recaptcha.sh`. 4. The script inserts the value directly into the `createTask` request body. 5. The crafted value changes or corrupts the JSON structu ...[truncated 1012 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Construct JSON with a serializer such as `jq` instead of interpolating strings: ```bash if [ -z "${CAPMONSTER_API_KEY:-}" ]; then echo "CAPMONSTER_API_KEY is required" >&2 exit 1 fi case "$WEBSITE_URL" in http://*|https://*) ;; *) echo "website_url must use HTTP or HTTPS" >&2 exit 1 ;; esac PAYLOAD=$(jq -n \ --arg key "$CAPMONSTER_API_KEY" \ --arg url "$WEBSITE_URL" \ --arg sitekey "$SITEKEY" \ '{ clientKey: $key, task: { type: "RecaptchaV2TaskProxyless", websiteURL: $url, websiteKey: $sitekey } }') RESPONSE=$(curl --fail-with-body -sS \ -X POST https://api.capmonster.cloud/createTask \ -H 'Content-Type: application/json' \ --data-binary "$PAYLOAD") ``` Additional hardening should include: 1. Reject missing API keys before making network requests. 2. Restrict target URLs to `http` and `https`; apply a domain allowlist when automation is intended only for approved sites. 3. Validate site-key length and permitted character format before submission. 4. Use `curl --fail-with-body -sS` and explicitly handle transport and HTTP errors. 5. Confirm that `.taskId`, `.errorId`, and result fields have the expected types before using them. 6. Apply account-side spending limits, balance alerts, and API-key rotation procedures to reduce billing exposure. ]]>
