T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/mint-via-bankr.sh:139
- Finding
- Unvalidated Network Endpoints Can Receive Bankr Credentials or User-Selected Media<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/lib.sh:130-145` - `scripts/mint-via-bankr.sh:139-154` - `scripts/lib.sh:60-61` - `scripts/mint-art.sh:102-104` - `scripts/pin-metadata.mjs:89-108` - `scripts/pin-metadata.mjs:181-183` **Vulnerability Type**: Unvalidated credential and media transmission destinations **Risk Level**: Medium ### Vulnerable Code The Bankr API URL is read from external configuration without validating its scheme or hostname: ```bash resolve_bankr_api_url() { local config_path for config_path in \ "$HOME/.openclaw/skills/bankr/config.json" \ "$HOME/.openclaw/workspace/skills/bankr/config.json" \ "$HOME/.bankr/config.json" do if [ -f "$config_path" ]; then local value value="$(jq -r '.apiUrl // empty' "$config_path")" if [ -n "$value" ]; then echo "$value" return fi fi done echo "https://api.bankr.bot" } ``` The resolved URL receives the real Bankr API key in an HTTP header: ```bash BANKR_API_KEY="$(resolve_bankr_api_key)" BANKR_API_URL="$(resolve_bankr_api_url)" REQUEST_PAYLOAD="$(jq -n \ --arg to "$COLLECTION_CONTRACT" \ --argjson chainId "$CHAIN_ID" \ --arg data "$CALLDATA" \ --arg description "$DESCRIPTION" \ '{ transaction: { to: $to, chainId: $chainId, value: "0", data: $data }, description: $description, waitForConfirmation: true }')" RESPONSE="$(curl -sS --max-time "$BANKR_SUBMIT_TIMEOUT_SECONDS" -X POST "$BANKR_API_URL/agent/submit" \ -H "X-API-Key: $BANKR_API_KEY" \ -H "Content-Type: application/json" \ -d "$REQUEST_PAYLOAD")" ``` The SuperRare-compatible media API endpoint is also configurable without destination validation: ```bash CONFIG_API_BASE_URL="$(jq -r '.apiBaseUrl // "https://api.superrare.org"' "$CONFIG_FILE")" ``` ```bash PIN_ARGS=(--name "$NAME" --description "$DESCRIPTION" --image "$IMAGE" --api-base-url "$CONFIG_API_BASE_URL") ``` The media upload implementat ...[truncated 5459 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Pin credential-bearing requests to a trusted endpoint** - Use `https://api.bankr.bot` as the only default destination. - Maintain an explicit allowlist of approved Bankr hostnames. - Do not send `X-API-Key` to an endpoint outside that allowlist without a separate, explicit opt-in intended for development environments. 2. **Enforce secure URL parsing** - Parse URLs rather than validating them with substring or prefix comparisons. - Require the `https:` scheme. - Reject URLs containing embedded usernames or passwords. - Validate the normalized hostname and effective port. - Disable unexpected redirects for credential-bearing requests, or verify every redirect destination before forwarding the authorization header. 3. **Separate endpoint trust from credential discovery** - Do not automatically combine an API key from the environment with an API URL from a different configuration source. - Store trusted endpoint selection in a protected setting or require the key and endpoint to come from the same explicitly selected profile. - Check ownership and permissions of credential-bearing configuration files where practical. 4. **Validate media API and upload destinations** - Require HTTPS for `apiBaseUrl`. - Default to and allowlist `api.superrare.org` for production use. - Validate each returned presigned URL against expected storage-provider hostnames and schemes before uploading. - Resolve and reject loopback, link-local, private-network, and cloud metadata destinations unless an explicit development mode requires them. 5. **Add explicit user confirmation for non-default endpoints** - Display the normalized API hostname before reading or uploading media. - Require a dedicated flag such as `--allow-custom-api-endpoint` for custom destinations. - Clearly warn that selected files and metadata will be transmitted to that host. 6. **Minimize credential exposure** - Use `curl ...[truncated 606 chars]
