T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:47
- Finding
- Permanent API Token Can Be Disclosed to an Untrusted Configurable Server<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 10–11, 29, 47–48, 56–57, and 82–86 **Vulnerability Type**: Unrestricted credential transmission to a configurable endpoint **Risk Level**: Medium ### Vulnerable Code The skill declares a permanent API credential and permits the API server URL to be changed: ```yaml env: - BEAVERHABITS_API_KEY - SERVER_URL (optional, defaults to https://beaverhabits.com) ``` ```markdown | `SERVER_URL` | No | `https://beaverhabits.com` | Your Beaver Habits server URL (for self-hosted instances) | ``` All documented requests send the bearer credential to the configured server without validating its scheme or destination: ```bash curl -s -H "Authorization: Bearer $BEAVERHABITS_API_KEY" \ "${SERVER_URL:-https://beaverhabits.com}/api/v1/habits" ``` ```bash curl -s -H "Authorization: Bearer $BEAVERHABITS_API_KEY" \ "${SERVER_URL:-https://beaverhabits.com}/api/v1/habits/{habit_id}/completions?date_fmt=%25d-%25m-%25Y&date_start={start}&date_end={end}&limit=100&sort=asc" ``` ```bash curl -s -X POST \ -H "Authorization: Bearer $BEAVERHABITS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"date": "20-02-2026", "done": true, "date_fmt": "%d-%m-%Y"}' \ "${SERVER_URL:-https://beaverhabits.com}/api/v1/habits/{habit_id}/completions" ``` ### Technical Analysis `SERVER_URL` is used directly as the destination of authenticated `curl` requests. The skill does not require HTTPS, validate the URL scheme, restrict the destination to an approved host, or request confirmation before sending the credential to a non-default server. Consequently, anyone able to influence the skill's `SERVER_URL` environment variable can redirect authenticated requests to an attacker-controlled endpoint. The `Authorization: Bearer` header contains the permanent `BEAVERHABITS_API_KEY`, so the receiving endpoint can capture and reuse it. Configuring a plaintext HTTP URL would also expose the token to network interception. ...[truncated 1678 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Require encrypted transport** - Reject destinations that do not use `https://`. - Permit plaintext HTTP only through an explicit, clearly documented development-only override. - Do not disable TLS certificate verification. 2. **Validate the destination** - Parse and validate `SERVER_URL` before attaching the authorization header. - Use an allowlist containing `beaverhabits.com` and explicitly configured trusted self-hosted domains. - Reject URLs containing embedded user information, unexpected schemes, or malformed host components. 3. **Require informed confirmation** - Before sending the token to a non-default host for the first time, show the normalized hostname and obtain explicit user approval. - Clearly state that the selected server will receive the bearer credential. 4. **Separate credentials by instance** - Recommend generating a dedicated token for each self-hosted instance. - Never reuse the production `beaverhabits.com` token with an unrelated self-hosted server. - Prefer narrowly scoped and expiring tokens where the API supports them. 5. **Prevent credential forwarding during redirects** - Avoid automatically following redirects for authenticated requests. - If redirects are necessary, ensure the authorization header is never forwarded to another origin. 6. **Provide recovery guidance** - Instruct users to revoke and regenerate the token immediately if it may have been sent to an untrusted endpoint. - Review habit data for unauthorized reads or modifications after suspected exposure. ]]>
