T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/fetch-asr-recordings.mjs:11
- Finding
- Bearer Token Forwarding to Arbitrary Plaintext Endpoints<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch-asr-recordings.mjs:11-18`, `scripts/fetch-asr-recordings.mjs:57-67`, and `scripts/fetch-asr-recordings.mjs:103-124` **Vulnerability Type**: Arbitrary credential destination and insecure transport **Risk Level**: High ### Vulnerable Code ```js function isHttpBaseUrl(value) { return /^https?:\/\//i.test(String(value ?? "").trim()); } function normalizeBaseUrl(value) { if (!isHttpBaseUrl(value)) { return DEFAULT_BASE_URL; } return String(value).trim().replace(/\/+$/, ""); } ``` ```js function resolveBaseUrl(argvBase) { if (isHttpBaseUrl(argvBase)) { return normalizeBaseUrl(argvBase); } const fromEnv = process.env.LEGION_HARDWARE_BASE_URL?.trim(); if (isHttpBaseUrl(fromEnv)) { return normalizeBaseUrl(fromEnv); } return DEFAULT_BASE_URL; } ``` ```js async function fetchRecordings(root, { userId, orgId, startTime, endTime, token }) { const headers = { Authorization: `Bearer ${token}`, Accept: "application/json", }; const getUrl = new URL(`${root}/api/recordings/asr-completed`); getUrl.searchParams.set("userId", userId); getUrl.searchParams.set("orgId", orgId); getUrl.searchParams.set("startTime", startTime); getUrl.searchParams.set("endTime", endTime); let res = await fetch(getUrl, { method: "GET", headers }); if (res.status !== 405) { return { res, method: "GET" }; } res = await fetch(`${root}/api/recordings/asr-completed`, { method: "POST", headers: { ...headers, "Content-Type": "application/json" }, body: JSON.stringify({ userId, orgId, startTime, endTime }), }); return { res, method: "POST" }; } ``` ### Technical Analysis The base URL may be supplied through a command-line argument or `LEGION_HARDWARE_BASE_URL`. Validation only checks whether the value begins with `http://` or `https://`; it does not enforce TLS, validate the destination against an allowlist, or bind the credential to the intended Legion H ...[truncated 1590 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Require `https://` for every credential-bearing request. - Permit only explicitly configured Legion Hardware hostnames and ports. - Parse the URL and validate `protocol`, `hostname`, and `port` independently; do not rely on a prefix regular expression. - Reject embedded credentials and unexpected URL components. - Disable redirects for authenticated requests or revalidate the origin before following each redirect. - Do not forward an authorization header across origins. - Prefer a fixed service endpoint supplied by trusted deployment configuration rather than command-line input. - If an internal service cannot support HTTPS, place it behind authenticated TLS or use mTLS over a tightly controlled network. - Rotate any token that may previously have been transmitted over an untrusted or plaintext connection. ]]>
