T05 · Unauthorized Access and Privilege Escalation
- Location
core.mjs:244- Finding
Unrestricted Local File Read Through Image Editing Input
- Content
View full analysis
3) throw new Error('Maximum 3 source images'); // Build input with image(s) + text prompt const content = []; for (const img of images) { // If it looks like a file path, read and base64 encode let imageUrl = img; if (!img.startsWith('http') && !img.startsWith('data:')) { const data = readFileSync(img); const ext = img.split('.').pop().toLowerCase(); const mime = ext === 'png' ? 'image/png' : ext === 'webp' ? 'image/webp' : 'image/jpeg'; imageUrl = `data:${mime};base64,${data.toString('base64')}`; } content.push({ type: 'image_url', image_url: { url: imageUrl } }); } ``` ### Technical Analysis The `edit_image` function interprets every string that does not begin with `http` or `data:` as a local filesystem path. It then passes that attacker-controlled path directly to `readFileSync`. No security boundary is enforced around the path. In particular, the implementation does not: - Restrict access to an approved image directory. - Resolve and validate canonical paths. - prevent directory traversal or absolute paths. - Reject symbolic links or non-regular files. - Verify that the content is actually a supported image. - Limit the maximum file size before loading the entire file into memory. The function is reachable through the MCP tool handler in `mcp-server.mjs:132-134`, where caller-provided parameters are forwarded directly to `edit_image`: ```javascript case 'grok_edit_image': result = await edit_image(params); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; ``` The MCP schema describes the ...[truncated 2492 chars]- Remediation
View remediation
