GitHub Advisoryadvisory · npm
GHSA-8q49-2h5h-434x FrontMCP: Server-Side Request Forgery (SSRF) in the OpenAPI adapter spec-change poller
MEDIUM
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
- https://github.com/agentfront/frontmcp/security/advisories/GHSA-8q49-2h5h-434x web
- https://github.com/agentfront/frontmcp/pull/510 web
- https://github.com/agentfront/frontmcp/commit/077201e109bf6f45dbc85c36d6bd77ded18ab13e web
- https://github.com/agentfront/frontmcp package
- https://github.com/agentfront/frontmcp/releases/tag/v1.5.6 web