T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/techsnif-cli.cjs:3556
- Finding
- Arbitrary and Insecure API Endpoint Override<![CDATA[ ## Vulnerability Details **File Location**: `scripts/techsnif-cli.cjs`, lines 3556–3584 and 3657–3659 **Vulnerability Type**: Arbitrary outbound requests, plaintext HTTP support, and untrusted content injection **Risk Level**: Medium ### Vulnerable Code ```js var DEFAULT_API_URL = (process.env.TECHSNIF_API_URL || "https://api.techsnif.com").replace(/\/+$/, ""); function getApiUrl(options) { const rawUrl = (options?.apiUrl || DEFAULT_API_URL).trim().replace(/\/+$/, ""); const parsed = new URL(rawUrl); if (parsed.protocol !== "http:" && parsed.protocol !== "https:") { throw new Error(`Unsupported API URL protocol "${parsed.protocol}". Use http:// or https://.`); } return parsed.toString().replace(/\/+$/, ""); } async function fetchJson(path, params, options) { const url = new URL(`${getApiUrl(options)}${path}`); for (const [key, value] of Object.entries(params)) { if (value) url.searchParams.set(key, value); } const response = await fetch(url.toString(), { headers: { Accept: "application/json" } }); ``` The endpoint is also exposed as a command-line option: ```js function addCommonReadOptions(command) { command.option("--json", "Output machine-readable JSON").option("--api-url <url>", "Override the TechSnif API base URL", getDefaultApiUrl()); return command; } ``` ### Technical Analysis The CLI permits the API base URL to be replaced through either the `TECHSNIF_API_URL` environment variable or the `--api-url` command-line option. Validation only checks whether the scheme is HTTP or HTTPS; it does not restrict the destination host, reject private or loopback addresses, or require encrypted transport. Consequently, an attacker who can influence the execution environment or generated CLI arguments can redirect requests to: - An attacker-controlled server that returns forged article data. - A plaintext HTTP endpoint vulnerable to interception and response modification. - Internal, loopback, or link-local ...[truncated 2328 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Pin the production endpoint** Remove the runtime endpoint override and always use the expected HTTPS origin: ```js const DEFAULT_API_URL = "https://api.techsnif.com"; ``` 2. **Require HTTPS** If endpoint overrides are necessary for controlled development or testing, reject plaintext HTTP: ```js if (parsed.protocol !== "https:") { throw new Error("Only HTTPS API endpoints are permitted."); } ``` 3. **Apply an explicit host allowlist** Permit only approved API hostnames and reject alternate ports unless they are specifically required: ```js const ALLOWED_HOSTS = new Set(["api.techsnif.com"]); if (!ALLOWED_HOSTS.has(parsed.hostname) || parsed.port) { throw new Error("Unapproved API endpoint."); } ``` 4. **Block internal destinations** If arbitrary destinations must remain supported, resolve the hostname before connecting and reject loopback, private, link-local, multicast, and reserved IPv4 and IPv6 ranges. Revalidate every redirect destination and defend against DNS rebinding. 5. **Disable automatic cross-origin redirects** Use a restrictive redirect policy or manually validate every redirect before following it. 6. **Separate development configuration** Gate custom API endpoints behind an explicit development mode that is disabled by default and cannot be activated through ordinary Skill-generated arguments. 7. **Treat remote content as untrusted** Ensure downstream Agent prompts clearly delimit article data and state that instructions contained in titles, excerpts, or article bodies must not be followed. 8. **Document network behavior** Update `SKILL.md` to disclose any retained endpoint override, its intended development-only purpose, and the security restrictions applied to it. ]]>
