auth-fetch-mcp: SSRF and disk exfiltration via unvalidated auth_fetch and download_media URLs
Date: 2026-05
Affected: npm/auth-fetch-mcp
Attack vector: prompt-injection
Category: vulnerability-disclosure
Severity: High
CWE: CWE-918
CVSS: 8.2 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N)

# SSRF + disk-exfil in `download_media` and `auth_fetch` tools — ymw0407/auth-fetch-mcp ## Severity The `download_media` and `auth_fetch` MCP tools accept arbitrary URLs and reach them as the MCP server process, with `download_media` additionally persisting the fetched response body to a user-controlled output directory. An MCP client (LLM under prompt injection, malicious peer) can drive the server to fetch loopback / link-local / private-range hosts (cloud-instance metadata, internal services, host-bound services) and exfiltrate the response. ## Vulnerability chain ### Site 1: `download_media` — SSRF + disk-write chain `src/tools.ts:200-274` ```ts server.registerTool("download_media", { inputSchema: { urls: z.array(z.string()).describe("One or more URLs to download"), output_dir: z.string().optional()..., }, }, async ({ urls, output_dir }) => { ... for (const url of urls) { try { const response = await ctx.request.get(url); // line 238 — no validation ... const body = await response.body(); ... const filePath = path.join(dir, `file-${++counter}${ext}`); fs.writeFileSync(filePath, body); // line 257 — writes response to disk ``` `urls` and `output_dir` are user-controlled. The handler iterates each URL (line 236) and calls `ctx.request.get(url)` (Playwright's `APIRequestContext.get`) without checking the destination. The response body is written to `path.join(output_dir, file-N.ext)`. Internal-servic


Mitigations:

Architectural layers (MAESTRO):