T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/lmstudio-api.mjs:45
- Finding
- Unrestricted API endpoint permits disclosure of private prompts to remote servers<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lmstudio-api.mjs:12, 45-72, 188`; related endpoint handling also appears in `scripts/load.mjs:8-19, 32`, `scripts/unload.mjs:9-32, 60`, and `scripts/test.mjs:9-59, 71` **Vulnerability Type**: Unrestricted network destination and plaintext transmission of potentially sensitive data **Risk Level**: High ### Code Snippet ```javascript const BASE_URL = process.env.LM_STUDIO_API_URL || 'http://127.0.0.1:1234'; ``` ```javascript const url = `${apiUrl.replace(/\/$/, '')}/api/v1/chat`; const payload = { model, input: taskContent, store: true, temperature: parseFloat(temperature), max_output_tokens: parseInt(maxOutputTokens) }; if (previousResponseId) payload.previous_response_id = previousResponseId; let lastError = null; for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) { try { if (logPath) { fs.writeFileSync(logPath, JSON.stringify({ request: payload, attempt }, null, 2) + '\n', { flag: 'a' }); } const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer lmstudio' }, body: JSON.stringify(payload) }); ``` ```javascript else if (arg.startsWith('--api-url=')) options.apiUrl = arg.split('=')[1]; ``` The same unrestricted URL pattern is used by the other helper scripts: ```javascript const BASE_URL = process.env.LM_STUDIO_API_URL || 'http://127.0.0.1:1234'; ``` ```javascript if (arg.startsWith('--api-url=')) apiUrl = arg.split('=')[1]; ``` ### Technical Analysis The Skill declares that processing is local and suitable for privacy-sensitive work, with a default LM Studio URL of `http://127.0.0.1:1234`. However, the destination can be replaced without validation through either the `LM_STUDIO_API_URL` environment variable or the `--api-url` argument. The main chat helper sends the complete task text, model identifier, and optional previous response identifier ...[truncated 2683 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Restrict the default operating mode to loopback destinations such as `127.0.0.1`, `::1`, and `localhost`. 2. Parse endpoints with the standard `URL` class rather than constructing URLs through string concatenation. 3. Reject non-loopback endpoints unless the user supplies a separate, explicit option such as `--allow-remote-api`. 4. Require HTTPS whenever remote access is explicitly enabled. 5. Resolve hostnames and verify that the resolved addresses comply with the intended network policy. Account for IPv4, IPv6, alternative loopback notation, and DNS rebinding. 6. Disable automatic cross-origin redirects or validate the destination of every redirect. 7. Display a clear warning before sending prompt content remotely, explaining that remote mode invalidates the local-only privacy guarantee. 8. Consider removing `--api-url` from normal agent-generated invocations and placing remote endpoint configuration in a trusted administrator-controlled configuration file. 9. Document exactly which fields are transmitted: task text, model identifier, response identifier, and generation settings. 10. Apply the same endpoint validation consistently to `lmstudio-api.mjs`, `load.mjs`, `unload.mjs`, and `test.mjs`. ]]>
