T09 · Insecure Skill Coding Practices
Warning
- Location
- references/api-playbook.md:49
- Finding
- Configurable External Endpoint Can Receive Bearer Tokens and Signed Agent Data<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:28-44, 46-54, 105-108, 127-139`; `references/api-playbook.md:3-10, 49-54, 64-74` **Vulnerability Type**: Unvalidated credential destination and sensitive-data disclosure **Risk Level**: Medium ### Vulnerable Code Snippets `SKILL.md:28-44`: ```markdown ## Security boundary (read first) This skill exchanges bearer tokens and signed requests with an external A2A service. Do not send credentials or signatures unless the endpoint is explicitly trusted. Default endpoint (current deployment): - Base URL: `https://openclawagents-a2a-6gaqf.ondigitalocean.app` Override endpoint via env when needed: - `A2A_BASE_URL` Reference/source: - Repo: `https://github.com/chefbc2k/openclawagents-a2a` (deployment branch may vary) Before first use in a new environment: 1. Confirm endpoint ownership/control. 2. Confirm TLS and expected hostname. 3. Confirm this endpoint is approved for agent identifiers/tokens. ``` `SKILL.md:46-54`: ```markdown ## Required credentials and config Declare and justify these before use: - `A2A_BASE_URL` (required in non-default env): target A2A service - `A2A_AGENT_KEY_B64` (required for headless register/signing): scoped agent keypair/secret - `A2A_BEARER_TOKEN` (runtime-issued): short-lived machine token from `/v1/agent/register-headless` Equivalent naming accepted by some clients: - `agent_key` - `agent_shared_key` ``` `SKILL.md:127-139`: ```markdown ## 5) Exchange messages / end call Use canonical A2A endpoint: - `POST /interop/a2a` Types: - `call.message` - `call.end` ### Signing recipe (required) `auth_proof` fields: - `bearer_jwt` - `request_signature` (base64 HMAC-SHA256) - `timestamp` (unix seconds) - `nonce` (unique, one-time) ``` `references/api-playbook.md:49-54`: ```bash ## Place call ```bash curl -s -X POST "$BASE/v1/call/place" \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d '{"from_number":"+a-100001","target":"@callee1","task ...[truncated 3422 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Enforce an explicit allowlist of approved HTTPS origins before sending any credential-bearing request. 2. Parse and compare the URL by scheme, normalized hostname, and port rather than using substring or suffix matching. 3. Reject non-HTTPS URLs, embedded credentials, unexpected ports, IP-literal destinations, malformed URLs, and redirects to a different origin. 4. Disable automatic redirects for authenticated requests, or strip authorization data and repeat origin validation before following a redirect. 5. Bind issued bearer tokens to an explicit audience representing the approved A2A service, and validate that audience server-side. 6. Invalidate existing tokens whenever `A2A_BASE_URL` changes. Require fresh registration against the newly approved endpoint rather than forwarding an existing token. 7. Use short-lived, narrowly scoped tokens with server-side revocation and rotation support. 8. Do not include `bearer_jwt` inside message bodies unless the protocol strictly requires it. Prefer a standard authorization header and avoid logging authentication envelopes. 9. Replace raw documentation-driven `curl` workflows with a maintained client that centrally enforces origin validation, redirect policy, timeouts, response-size limits, and redaction. 10. Require an explicit user or administrator confirmation when selecting a non-default endpoint, showing the normalized destination and the classes of data that will be disclosed. 11. Redact bearer tokens, signatures, nonces, and complete authentication payloads from logs, errors, transcripts, and user-facing responses. 12. Document the intended token audience, expiration period, permitted API operations, and incident-response procedure for endpoint misconfiguration. ]]>
