T09 · Insecure Skill Coding Practices
- Location
- scripts/_lib.mjs:6
- Finding
- Unrestricted API Base URL Can Exfiltrate Bearer Credentials and Sensitive Request Data## Vulnerability Details **File Location**: `scripts/_lib.mjs:6-7, 38-50`; `scripts/upload-file.mjs:6-7, 15-25` **Vulnerability Type**: Arbitrary authenticated request destination **Risk Level**: High ### Vulnerable Code `scripts/_lib.mjs:6-7, 38-50` ```js const API_KEY = (process.env.TMR_API_KEY ?? "").trim(); const BASE_URL = (process.env.TMR_BASE_URL ?? "https://tmrland.com/api/v1").replace(/\/$/, ""); export async function tmrFetchSafe(method, path, body = null) { const url = `${BASE_URL}${path}`; const opts = { method, headers: { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json", }, }; if (body !== null) { opts.body = JSON.stringify(body); } const resp = await fetch(url, opts); ``` `scripts/upload-file.mjs:6-7, 15-25` ```js const API_KEY = (process.env.TMR_API_KEY ?? "").trim(); const BASE_URL = (process.env.TMR_BASE_URL ?? "https://tmrland.com/api/v1").replace(/\/$/, ""); const filePath = positional[0]; const fileName = basename(filePath); const fileData = readFileSync(filePath); const formData = new FormData(); formData.append("file", new Blob([fileData]), fileName); const resp = await fetch(`${BASE_URL}/uploads/`, { method: "POST", headers: { "Authorization": `Bearer ${API_KEY}` }, body: formData, }); ``` ### Technical Analysis The destination of every authenticated API request is controlled by the `TMR_BASE_URL` environment variable. The code does not validate the URL scheme, hostname, port, embedded credentials, or origin before attaching `TMR_API_KEY` as a bearer credential. Consequently, any process or configuration source capable of setting this environment variable can redirect requests to an attacker-controlled server. The issue applies to all scripts using `tmrFetch` and to `upload-file.mjs`, which implements the same unsafe destination logic independently. Sensitive request bodies rou ...[truncated 2245 chars]
- Remediation
- ## Remediation Suggestions 1. Default to the fixed production origin `https://tmrland.com` and reject other origins unless custom deployment support is explicitly enabled. 2. Parse the configured value with `new URL()` and enforce: - The `https:` scheme. - An explicit allowlist of trusted hostnames. - Expected ports. - No embedded username or password. - An expected API path prefix. 3. Use separate credentials for custom deployments. Never send a production TMR Land key to a user-supplied origin. 4. Reject credential-bearing redirects or configure requests for manual redirect handling. Revalidate every redirect target before following it. 5. Centralize upload requests in the validated HTTP client instead of duplicating base URL and credential logic. 6. Add startup diagnostics that display the selected hostname without printing credentials and require explicit user confirmation for non-production endpoints. 7. Apply narrowly scoped API-key permissions so compromise of one key does not expose unrelated wallet, account, and administrative operations. 8. Add automated tests confirming that HTTP URLs, unapproved hosts, embedded credentials, unexpected ports, and cross-origin redirects are rejected.
