T09 · Insecure Skill Coding Practices
Warning
- Location
- src/index.ts:17
- Finding
- Unrestricted telemetry endpoint can expose the service API key and LLM usage metadata## Vulnerability Details **File Location**: `src/index.ts`, lines 17–40 **Vulnerability Type**: Unrestricted credential-bearing network destination **Risk Level**: Medium ### Vulnerable Code ```typescript const apiKey = config.api_key || process.env.OHMYTOKEN_API_KEY const endpoint = config.endpoint || DEFAULT_ENDPOINT if (!apiKey) { console.warn('[ohmytoken] No API key configured. Set OHMYTOKEN_API_KEY or config.api_key') return {} } return { name: 'ohmytoken-tracker', async onLLMResponse(usage: TokenUsage) { try { await fetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey, }, body: JSON.stringify({ model: usage.model || 'unknown', prompt_tokens: usage.prompt_tokens || 0, completion_tokens: usage.completion_tokens || 0, reasoning_tokens: usage.reasoning_tokens || 0, cached_tokens: usage.cached_tokens || 0, }), }) ``` ### Technical Analysis The Skill permits `config.endpoint` to specify an arbitrary network destination without validating its scheme or hostname. Every request to that destination includes the ohmytoken API key in the `X-API-Key` header, together with the model identifier and detailed token-usage telemetry. An endpoint using plain HTTP exposes this information to network interception. An attacker-controlled HTTPS endpoint can directly collect the credential and telemetry. Arbitrary credential-bearing egress is broader than necessary for the declared hosted tracking functionality, whose documented service endpoint is `https://api.ohmytoken.dev/api/v1/ingest`. The transmitted data does not include prompts, responses, files, provider API keys, or arbitrary conversation content based on the reviewed implementation. Its scope is limited to the ohmytoken API key, model name, and prompt, completion, r ...[truncated 1266 chars]
- Remediation
- ## Remediation Suggestions 1. Remove the configurable endpoint if custom ingestion servers are not an essential supported feature. 2. Otherwise, parse the configured value with `URL` and require the `https:` scheme. 3. Restrict credential-bearing requests to an explicit hostname allowlist, preferably only `api.ohmytoken.dev`. 4. Reject embedded credentials, unexpected ports, malformed URLs, and destinations outside the allowlist. 5. Apply a restrictive redirect policy and ensure the API key is never forwarded to a different origin. 6. Consider separating custom-endpoint support from hosted-service authentication so the ohmytoken API key is not sent to third-party collectors. 7. Surface configuration and delivery errors safely instead of silently suppressing every failure, while ensuring logs never contain the API key. 8. Update the privacy documentation to match the implementation: it currently describes four transmitted values including a timestamp, while the code sends five usage fields and no timestamp.
