GitHub Advisoryadvisory · npm

GHSA-8q49-2h5h-434x FrontMCP: Server-Side Request Forgery (SSRF) in the OpenAPI adapter spec-change poller

MEDIUM Published 2026-07-24 Modified 2026-07-24 Official page ↗
Ecosystem
npm
Packages
@frontmcp/adapters
Severity
Moderate
CVSS vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Weaknesses
CWE-918
Reviewed
2026-07-24

Affected packages

• npm @frontmcp/adapters: < 1.5.6 → fixed in 1.5.6

Description

Summary The OpenAPI adapter's spec-change poller (`OpenApiSpecPoller`) re-fetched the configured spec `url` on a timer using a raw global `fetch()`, bypassing the SSRF guard (`safeFetch` / `assertUrlSafe`) that `OpenAPIToolGenerator.fromURL()` applies to the initial spec load. As a result, the pinning/DNS-resolution hardening delivered via `mcp-from-openapi >= 2.5.0` (advisory GHSA-65h7-9wrw-629c) protected the initial load but not the recurring poll of the same URL. When polling is enabled against an untrusted or attacker-influenceable spec URL, this is an unguarded SSRF vector. Details The initial spec load is guarded. `OpenapiAdapter` resolves a secure `refResolution` policy and passes it to the guarded loader: ```ts // libs/adapters/src/openapi/openapi.adapter.ts — initializeGenerator() return await OpenAPIToolGenerator.fromURL(this.options.url, { // ... followRedirects: this.options.loadOptions?.followRedirects ?? false, refResolution, // secure default: external $refs off, internal targets blocked }); ``` But the poller — which re-fetches the same URL on every interval — did not: ```ts // libs/adapters/src/openapi/openapi-spec-poller.ts — doFetch() (vulnerable, controller.abort(), this.fetchTimeoutMs); try { const response = await fetch(this.url, { // = 2.5.0` (already a dependency at `2.5.1`), which exports `safeFetch` / `normalizeSsrfOptions` and performs the resolved-IP validation and connection pinning. Remediation Upgrade `@frontmcp/adapters` to `1.5.6` or later. No configuration change is required: polling now inherits the same secure defaults as the initial spec load (external targets blocked, redirects not followed). To poll a genuinely internal or localhost spec server in a trusted environment, opt in explicitly with `loadOptions.refResolution.allowInternalIPs: true` — the same knob that gates the initial load. Workarounds For users who cannot upgrade immediately: • disable polling (`polling.enabled: false`) on adapters whose spec `url` is not a fixed, trusted, first-party value; or • only enable polling against spec URLs you fully control, served over HTTPS from a host that cannot be made to redirect to internal targets; and • enforce network egress controls / an allow-list at the platform layer so the server cannot reach internal ranges or cloud-metadata endpoints.

Related

Weakness · CWE (1)

  • CWE-918 Server-Side Request Forgery weakness

References