# FrontMCP and mcp-from-openapi have bypass of OpenAPI external $ref SSRF fix

FrontMCP's OpenAPI adapter still fetches external $refs to loopback via DNS names, redirects, and IPv4-mapped IPv6, bypassing the prior SSRF denylist fix.

- Payout: Research
- Severity: high
- Program: FrontMCP
- Found by: DavidCarliez
- Disclosed: 2026-09-11
- CVE: CVE-2026-59973
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-65h7-9wrw-629c
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-65h7-9wrw-629c
- Tags: area:ai domain:ai domain:web impact:internal-access kind:research platform:ghsa sev:high tech:nodejs tech:rest technique:incomplete-fix technique:source-review vuln:ssrf

**Target:** OpenAPI adapter external $ref dereferencing in mcp-from-openapi
**Root cause:** The prior fix applied a parsed-hostname string denylist before fetching, without resolving DNS, pinning the validated IP, revalidating redirects, or normalizing IPv4-mapped IPv6 forms.
**Steps:**
1. Start a loopback canary HTTP server on a port.
2. Build an OpenAPI spec whose request body schema contains an external `$ref` pointing at `http://127.0.0.1.nip.io:<port>/schema.json`.
3. Load it via `OpenAPIToolGenerator.fromJSON(spec, ...)` with default refResolution; the canary records a hit from the backend.
4. Repeat with `http://127.0.0.1.nip.io:<port>/redirect` which 302s to `http://127.0.0.1:<port>/schema.json`; canary records two hits.
5. Repeat with `http://[::ffff:127.0.0.1]:<port>/schema.json` and `http://[::ffff:7f00:1]:<port>/schema.json`; both reach the canary.
6. Control: direct `http://127.0.0.1:<port>/schema.json` is denied with zero hits.
**How found:** Reviewed the prior advisory's fix and noticed the guard only string-matches the parsed hostname before the HTTP resolver runs; hypothesized DNS resolution, redirect following, and IPv6 normalization would slip past, then built a canary harness with per-case specs and a direct-127 control to confirm.
**Exploitation:** An attacker who can supply or configure an OpenAPI spec in a hosted/multi-user FrontMCP deployment embeds an external $ref using a DNS name resolving to loopback, a redirect chain, or IPv4-mapped IPv6; during tool generation the server fetches internal endpoints and returns/reflects the schema content.
**Escalation:** Chaining redirects after an allowed host and DNS-resolved hostnames defeats both hostname denylist and allowedHosts checks; fromURL() initial spec load remains unguarded entirely.
**Insight:** When auditing an SSRF denylist fix, test the gap between the string that is validated and the address actually connected to: DNS names resolving to loopback, redirect hops after an allowed host, and IPv4-mapped IPv6 literals are the standard three bypasses.

