T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/cursor-api.sh:47
- Finding
- Cursor API Key Disclosure Through an Unrestricted API Base Override<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cursor-api.sh:47`, `scripts/cursor-api.sh:579-589`, and `scripts/cursor-api.sh:618-647` **Vulnerability Type**: Credential disclosure through an attacker-controlled network destination **Risk Level**: High ### Vulnerable Code ```bash # Configuration readonly API_BASE="${CURSOR_API_BASE:-https://api.cursor.com/v0}" ``` ```bash # Get authorization header # Uses Basic auth with base64 encoding per Cursor API spec # The API key is read from CURSOR_API_KEY env var or config files # This is standard HTTP Basic authentication, not obfuscation get_auth_header() { local api_key credentials api_key=$(get_api_key) || return 1 credentials="${api_key}:" # Base64 encode for HTTP Basic Authentication (RFC 7617) # Format: base64(username:password) where username is API key, password is empty echo "Authorization: Basic $(printf '%s' "$credentials" | base64)" } ``` ```bash local curl_opts=( -s -w "\n%{http_code}" --connect-timeout "$CURL_CONNECT_TIMEOUT" --max-time "$CURL_MAX_TIME" ) local headers=(-H "Content-Type: application/json" -H "$(get_auth_header)") local url="${API_BASE}${endpoint}" verbose "API Request: $method $url" local response http_code curl_stderr local attempt=1 local retry_delay=2 while [[ $attempt -le $CURL_RETRY_COUNT ]]; do curl_stderr=$(mktemp) if [[ "$method" == "GET" ]]; then response=$(curl "${curl_opts[@]}" "${headers[@]}" "$url" 2>"$curl_stderr") || { error "curl failed: $(cat "$curl_stderr")" "$E_API_ERROR" } else if [[ -n "$body" ]]; then response=$(curl "${curl_opts[@]}" "${headers[@]}" -X "$method" -d "$body" "$url" 2>"$curl_stderr") || { error "curl failed: $(cat "$curl_stderr")" "$E_API_ERROR" } else response=$(curl "${curl_opts[@]}" "${headers[@]}" -X "$method" "$url" 2>"$curl_stderr") || { error "curl failed: $(ca ...[truncated 2437 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `CURSOR_API_BASE` from production use and hardcode the trusted endpoint: ```bash readonly API_BASE="https://api.cursor.com/v0" ``` 2. If an override is required for testing, require an explicit test mode and validate the complete origin: ```bash if [[ "${CURSOR_TEST_MODE:-false}" != "true" ]]; then API_BASE="https://api.cursor.com/v0" fi ``` 3. Allowlist trusted HTTPS origins rather than relying on a prefix or substring check. Parse and verify the scheme, hostname, port, and path independently. 4. Never send production credentials to a test endpoint. Require a separate test credential variable when an override is enabled. 5. Reject plaintext HTTP endpoints and malformed URLs. 6. Document the trust implications of endpoint overrides in `SECURITY.md`, `README.md`, `SKILL.md`, and `skill.json`. 7. Add automated tests proving that arbitrary domains, plaintext HTTP URLs, embedded user information, and unexpected ports are rejected before the Authorization header is created or transmitted. ]]>
