T09 · Insecure Skill Coding Practices
Error
- Location
- index.mjs:108
- Finding
- Full-page screenshots and API credentials can be transmitted to an unrestricted endpoint<![CDATA[ ## Vulnerability Details **File Location**: `index.mjs:34-69`, `index.mjs:108-130`, `index.mjs:604-630` **Vulnerability Type**: Sensitive-data exposure through an unrestricted network destination **Risk Level**: High ### Complete Code Snippet ```javascript function loadConfig(overrides = {}) { if (overrides.apiKey) { return { baseUrl: overrides.baseUrl || 'https://dashscope.aliyuncs.com/compatible-mode/v1', apiKey: overrides.apiKey, model: overrides.model || 'qwen3-vl-plus' }; } const envApiKey = process.env.VISION_API_KEY || process.env.QWEN_API_KEY; if (envApiKey) { return { baseUrl: process.env.VISION_BASE_URL || process.env.QWEN_BASE_URL || 'https://dashscope.aliyuncs.com/compatible-mode/v1', apiKey: envApiKey, model: process.env.VISION_MODEL || process.env.QWEN_MODEL || 'qwen3-vl-plus' }; } ``` ```javascript const imageBuffer = fs.readFileSync(screenshotPath); const base64Image = imageBuffer.toString('base64'); const response = await fetch(`${config.baseUrl}/chat/completions`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${config.apiKey}` }, body: JSON.stringify({ model: config.model, messages: [ { role: 'user', content: [ { type: 'text', text: `This is a webpage screenshot. Identify the text in the CAPTCHA image. Return only the CAPTCHA text, normally 4-6 alphanumeric characters, without descriptions. Return "UNRECOGNIZABLE" if the CAPTCHA is not visible or cannot be recognized.` }, { type: 'image_url', image_url: { url: `data:image/png;base64,${base64Image}` } } ] } ], max_tokens: 20, temperature: 0.1 }) }); ``` ```javascript screenshots.page = path.join(WORKSPACE_DIR, `${outputPrefix}_page.png`); await page.screenshot({ path: screenshots.page, fullPage: true }); await page. ...[truncated 2946 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Locate the CAPTCHA element locally and capture only its bounding box instead of using a full-page screenshot. 2. Default to local OCR and require explicit user confirmation before any remote vision fallback. 3. Enforce HTTPS by parsing the endpoint with `new URL()` and rejecting protocols other than `https:`. 4. Maintain an explicit allowlist of trusted API origins. 5. Refuse to send an API key when the selected origin differs from the credential's configured provider. 6. Display the exact destination origin and data scope before transmission. 7. Redact sensitive form fields and page regions before producing any image sent remotely. 8. Set request timeouts, response-size limits, and redirect restrictions. In particular, prevent redirects to untrusted origins. 9. Use provider-specific credentials with minimum quota and scope, and support rapid credential revocation. 10. Document retention and privacy properties of the selected remote provider. ]]>
