fumadocs-openapi: createProxy() open proxy and SSRF by default
fumadocs-openapi createProxy() - an open forward proxy (SSRF) by default when no allowedOrigins is set; redirects bypass the allowlist (GHSA-7r23-3v7p-56ff)
Fixed in fumadocs-openapi 11.2.2 (2026-07-16): createProxy() now defaults to same-origin only and enforces the allowlist on every redirect. Track the fix at fuma-nama/fumadocs@6c949cb.
- Product
- fumadocs-openapi (npm) in fuma-nama/fumadocs
- Affected versions
- fumadocs-openapi before 11.2.2 (reviewed on 11.1.1). Fixed in 11.2.2 (2026-07-16).
- Severity
- MEDIUM
- Status
- Patched
- Weaknesses
- CWE-918Server-Side Request Forgery (SSRF)
- CWE-1327Binding to an Unrestricted IP Address
- GitHub advisory
- GHSA-7r23-3v7p-56ff
Private; accepted and closed by the maintainer, not published - CVE
- Pending (requested from MITRE)
- Published
- Credit
- Finder: Aaron Elijah Mars of Aeon. Tool: Aeon (https://www.aeon.fun).
What users should do now
- Upgrade fumadocs-openapi to 11.2.2 or later.
- Pass an explicit
allowedOriginslist (only the API origins your playground needs) or afilterRequestfunction tocreateProxy(). - If you cannot upgrade yet, remove the proxy route or put it behind authentication.
Summary
The createProxy() helper in fumadocs-openapi builds the route handler that the API playground uses to send requests. Before 11.2.2, its allowedOrigins and filterRequest options were optional and the origin check was skipped when neither was set, so a docs site that mounted the proxy route with the defaults became an unauthenticated open forward proxy. Anyone could make the server fetch internal addresses, such as cloud metadata endpoints or localhost admin ports. Even with an allowlist, redirects were followed without re-checking the destination.
Affected versions
fumadocs-openapi before 11.2.2, on any deployed site that mounts a createProxy() route without allowedOrigins or filterRequest. Reviewed on 11.1.1.
Impact
- Default configuration. The route proxies any
?url=target. On a cloud host this can expose instance metadata credentials, and any internal service, localhost port or private-range host the server can reach is in scope. Inbound headers are forwarded and a?cookie=parameter sets the outgoingCookieheader, so the route also works as an anonymizing proxy. - With an allowlist. Only the first URL was checked.
fetch()followed redirects by default, so an allowed upstream that redirects to an internal host bypassed the allowlist.
Affected code
packages/openapi/src/server/proxy.ts: the origin check ran onlyif (allowedOrigins && ...), andfetch()was called with the defaultredirect: 'follow'
Fix
- Fumadocs 11.2.2 (6c949cb) makes
allowedOriginsdefault to the proxy route's own origin, logs a warning when no allowlist is configured, and enforces the allowlist on each redirect hop.
Detection (for defenders)
Review access logs for the proxy route (often /api/proxy) with url= values pointing at private, loopback or link-local addresses, cloud metadata hosts, or origins your playground never uses.
Timeline
- Reported to the maintainer by email.
- Maintainer ships the fix in fumadocs-openapi 11.2.2 (6c949cb).
- Formal report via GitHub PVR (GHSA-7r23-3v7p-56ff) once it was enabled; the maintainer accepts and closes it the same day without publishing.
- CVE IDs requested from MITRE.
- Public write-up.
Credit
Finder: Aaron Elijah Mars of Aeon. Tool: Aeon.
References
- Fix commit: fuma-nama/fumadocs@6c949cb
- Fixed release: fumadocs-openapi 11.2.2
- GitHub advisory: GHSA-7r23-3v7p-56ff (private; accepted and closed, not published)
- CVE: pending (requested from MITRE)
- Affected repository: fuma-nama/fumadocs