Listen to this Post
The vulnerability exists in auth-fetch-mcp v3.0.1 within the assertSafeUrl() function in src/security.ts, which is designed to block requests to private and loopback addresses. The isPrivateV6() function fails to detect IPv4-mapped IPv6 loopback addresses after they have been hex-normalized by the Node.js WHATWG URL parser. When an attacker supplies a URL such as http://[::ffff:127.0.0.1]:PORT/, the parser converts the hostname to [::ffff:7f00:1]. The code then extracts the suffix after “::ffff:” and checks if it is a valid IPv4 address using net.isIPv4(). Since “7f00:1” is not in dotted-decimal format, net.isIPv4() returns false, and the private-IP check is bypassed entirely. The URL is then passed to the browser or HTTP client, allowing the MCP tool to reach loopback services that should be blocked. This issue is exploitable under default configuration without any special environment variables and carries a CVSS v3.1 Base Score of 7.4 (High). The vulnerable code path is triggered by the auth_fetch and download_media MCP tools, both of which accept user-controlled URLs. The root cause is in src/security.ts lines 46-50, where the IPv4-mapped IPv6 suffix is not decoded from its hex-normalized form before the private-IP check. The data flow for auth_fetch starts at src/tools.ts:119, passes through navigateTo() in src/browser.ts:58, and calls assertSafeUrl() in src/security.ts:74-108. For download_media, the flow is similar through src/tools.ts:198-210 and src/tools.ts:233-234. Dynamic confirmation shows that direct loopback URLs are correctly blocked, but the IPv4-mapped IPv6 form bypasses the guard and reaches the internal service, as demonstrated by a PoC running inside a Docker container with –network=host.
DailyCVE Form:
Platform: auth-fetch-mcp
Version: v3.0.1
Vulnerability: SSRF Bypass
Severity: High
date: 2026-07-01
Prediction: Unknown
What Undercode Say:
git clone https://github.com/ymw0407/auth-fetch-mcp.git cd auth-fetch-mcp npm ci npm run build npx playwright install --with-deps chromium
node -e 'require("http").createServer((q,r)=>r.end("
<h1>INTERNAL_SECRET_MARKER</h1>
")).listen(31337,"127.0.0.1")'
{
"tool": "auth_fetch",
"arguments": {
"url": "http://[::ffff:127.0.0.1]:31337/"
}
}
Exploit:
An attacker supplies a URL with an IPv4-mapped IPv6 loopback address in hex-normalized form, e.g., http://[::ffff:7f00:1]:31337/. The Node.js URL parser normalizes the host, and isPrivateV6() fails to detect it as private, allowing the request to reach internal services bound to 127.0.0.1 or other private IPv4 ranges. The response from the internal service is returned to the attacker, compromising confidentiality.
Protection:
Decode the hex-encoded IPv4-mapped suffix before passing it to isPrivateV4() in src/security.ts. Add a regular expression to extract the two hex parts, convert them to decimal, and reconstruct the dotted-decimal IPv4 address. Additionally, implement a BrowserContext route guard in src/browser.ts to re-validate every navigation URL, including redirect targets, through assertSafeUrl().
Impact:
An attacker can read responses from any HTTP service on the user’s loopback interface or internal network, including local dev servers, admin panels, credential endpoints, and metadata services. Confidentiality is fully compromised (C:H), while integrity and availability are not directly affected.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

