T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/client.js:11
- Finding
- Compute Gateway Bearer Token Can Be Transmitted over Plaintext HTTP## Vulnerability Details **File Location**: `scripts/client.js:11-28` **Vulnerability Type**: Missing HTTPS protocol enforcement **Risk Level**: Medium ```js const baseUrl = process.env.MCP_COMPUTE_URL; const apiKey = process.env.MCP_COMPUTE_API_KEY; function assertEnv() { if (!baseUrl) throw new Error('Missing MCP_COMPUTE_URL'); if (!apiKey) throw new Error('Missing MCP_COMPUTE_API_KEY'); } async function post(path, body) { assertEnv(); const url = new URL(path, baseUrl); const res = await request(url, { method: 'POST', headers: { 'content-type': 'application/json', 'authorization': `Bearer ${apiKey}` }, body: JSON.stringify(body ?? {}) }); ``` The same unrestricted URL construction and bearer-token transmission pattern is also used by the PUT, GET, and DELETE helpers at `scripts/client.js:38-110`. ### Technical Analysis The documentation states that the private compute gateway is contacted over HTTPS, but `assertEnv()` only verifies that `MCP_COMPUTE_URL` and `MCP_COMPUTE_API_KEY` are present. It does not require the parsed URL to use the `https:` protocol. If `MCP_COMPUTE_URL` is configured with an `http://` URL, the client sends the bearer token and request contents without transport encryption. Sensitive contents can include command strings, command environment values, session information, and uploaded or downloaded artifacts. ### Attack Path 1. A user, deployment script, compromised configuration source, or social-engineering instruction supplies an `MCP_COMPUTE_URL` beginning with `http://`. 2. `assertEnv()` accepts the value because it only checks whether it is non-empty. 3. The client creates requests to the plaintext endpoint and includes `Authorization: Bearer ${apiKey}`. 4. An attacker with a network position between the client and gateway intercepts the bearer token and sensitive request or response data. 5. The attacker reuses the token ...[truncated 455 chars]
- Remediation
- ## Remediation Suggestions - Parse and validate the base URL once during initialization. - Reject every protocol other than `https:`. - If plaintext HTTP is necessary for local development, require an explicit opt-in flag and restrict its use to loopback addresses such as `127.0.0.1` or `::1`. - Reject URLs containing embedded credentials. - Add tests confirming that `http://`, malformed URLs, and unsupported protocols are rejected before any request is made. - Preserve normal TLS certificate verification and document that disabling certificate validation is unsupported. Example hardening: ```js function getValidatedBaseUrl() { if (!baseUrl) throw new Error('Missing MCP_COMPUTE_URL'); if (!apiKey) throw new Error('Missing MCP_COMPUTE_API_KEY'); const parsed = new URL(baseUrl); if (parsed.protocol !== 'https:') { throw new Error('MCP_COMPUTE_URL must use HTTPS'); } if (parsed.username || parsed.password) { throw new Error('MCP_COMPUTE_URL must not contain embedded credentials'); } return parsed; } ```
