other
- Location
index.mjs:111- Finding
Full Login-Page Screenshots Are Transmitted to a Configurable Remote Vision Provider
- Content
View full analysis
Vulnerability Details
File Location:
index.mjs:111-140, 612-636;recognize.mjs:134-176, 515-520
Vulnerability Type: Excessive sensitive-data disclosure
Risk Level: HighVulnerable Code
index.mjs:111-140:js 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: `这是一个网页截图,请识别验证码图片中的文字。 只返回验证码文字本身(通常是 4-6 位字母数字),不要任何其他描述或解释。 如果看不到验证码或无法识别,返回"UNRECOGNIZABLE"。` }, { type: 'image_url', image_url: { url: `data:image/png;base64,${base64Image}` } } ] } ], max_tokens: 20, temperature: 0.1 }) });index.mjs:612-636:js screenshots.page = path.join(WORKSPACE_DIR, `${outputPrefix}_page.png`); await page.screenshot({ path: screenshots.page, fullPage: true }); // ... screenshots.page = path.join(WORKSPACE_DIR, `${outputPrefix}_page.png`); await page.screenshot({ path: screenshots.page, fullPage: true }); analysis = await analyzePageWithVision(screenshots.page, config);recognize.mjs:134-176:js export async function recognizeFromBase64(imageBase64, config = {}) { const cfg = loadConfig(config); const requestBody = { model: cfg.model, messages: [{ role: 'user', content: [ { type: 'text', text: '请识别图片中的验证码文字,只返回验证码内容,不要任何其他描述。保持原始大小写,不要转换。' }, { type: 'image_url', image_url: { url: `data:image/png;base64,${imageBase64}` } } ] }], max_tokens: 100, temperature ...[truncated 3196 chars]- Remediation
View remediation
Remediation Suggestions
- Identify the CAPTCHA element locally and use an element-level screenshot:
js const captcha = page.locator(captchaSelector).first(); const imageBuffer = await captcha.screenshot(); - Never upload a full login page by default. If element detection fails, stop and request an explicit selector rather than silently falling back to a full-page image.
- Redact password fields, usernames, payment data, tokens, QR codes, and other sensitive regions before any remote request.
- Show the exact destination hostname and require explicit user consent before the first remote upload.
- Require HTTPS and validate the endpoint with
new URL(). Consider an allowlist for known providers, with a separate explicit opt-in for custom endpoints. - Do not forward a valuable provider credential to an untrusted custom endpoint. Use endpoint-specific credentials and document that bearer tokens are disclosed to the selected provider.
- Prefer local OCR when possible and use remote recognition only as an explicit fallback.
- Add tests asserting that the outbound image dimensions match the CAPTCHA element rather than the full page.
- Identify the CAPTCHA element locally and use an element-level screenshot:
