T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:3
- Finding
- Configurable API Endpoint Can Expose the Readeck Bearer Credential<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 3, 9–11, 18–21, 29–31, 37–39, 43–51 **Vulnerability Type**: Arbitrary credential destination and insufficient endpoint validation **Risk Level**: Medium ### Vulnerable Code ```markdown description: Readeck integration for saving and managing articles. Supports adding URLs, listing entries, and managing bookmarks via Readeck's API. Configure custom URL and API key per request or via environment variables READECK_URL and READECK_API_KEY. ``` ```markdown Configure Readeck access via: - Request parameters: `url` and `apiKey` - Environment variables: `READECK_URL` and `READECK_API_KEY` ``` ```bash curl -X POST "$READECK_URL/api/bookmarks" \ -H "Authorization: Bearer $READECK_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com/article"}' ``` ```bash curl "$READECK_URL/api/bookmarks?limit=20" \ -H "Authorization: Bearer $READECK_API_KEY" ``` ```bash curl "$READECK_URL/api/bookmarks/$ID" \ -H "Authorization: Bearer $READECK_API_KEY" ``` ```bash curl -X DELETE "$READECK_URL/api/bookmarks/$ID" \ -H "Authorization: Bearer $READECK_API_KEY" ``` ```bash curl -X PUT "$READECK_URL/api/bookmarks/$ID/status" \ -H "Authorization: Bearer $READECK_API_KEY" \ -H "Content-Type: application/json" \ -d '{"status": "read"}' ``` ### Technical Analysis The Skill allows the Readeck API base URL to be supplied through request configuration while separately allowing the bearer credential to come from the `READECK_API_KEY` environment variable. Every documented API operation attaches that credential to a request sent to the selected `READECK_URL`. No instructions require HTTPS, constrain the hostname and port, bind a credential to a specific trusted origin, or validate that a request-supplied URL belongs to the intended Readeck instance. Consequently, untrusted input that controls the base URL can determine where an existing environment-backed secret is transmitte ...[truncated 2084 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Treat the API origin as trusted configuration** - Do not accept `READECK_URL` from ordinary task content or untrusted request parameters. - Configure the Readeck origin administratively and keep it separate from user-provided article URLs. 2. **Bind credentials to an approved origin** - Associate each API key with a normalized scheme, hostname, and port. - Attach the `Authorization` header only after confirming that the destination exactly matches that origin. - Prefer an explicit allowlist rather than substring or suffix matching. 3. **Require transport security** - Permit only `https://` endpoints. - Reject embedded credentials, unexpected ports, malformed hosts, and non-HTTP schemes. - Do not disable TLS certificate verification. 4. **Control redirects** - Disable redirects for authenticated requests where possible. - If redirects are required, revalidate every destination and never forward authorization credentials to a different origin. 5. **Apply least privilege** - Use a dedicated Readeck token with only the operations required by this Skill. - Where supported, use separate read-only and write/delete credentials. - Rotate the key immediately if it may have been sent to an untrusted endpoint. 6. **Clarify trusted and untrusted parameters** - Rename the base URL parameter to an unambiguous name such as `readeckBaseUrl`. - Distinguish it from the article URL being saved. - Document that user-provided article URLs must only appear in the JSON request body and must never determine the authenticated API destination. ]]>
