enframe
- Type
- Repo
- Scanned
- Oct 29, 2026
- Version
- d5ed14eefc22
- Files read
- 53
Enframe turns any OpenAPI specification into an HTTP-based MCP server so AI agents can call the target API as tools. Its biggest risk is that unless the API specification defines OAuth2 scopes, the server runs without client authentication and lets anyone who can reach its network port make API requests using your configured API key.
What it can reach
- Network
- Listens for incoming MCP client connections over HTTP (port 8080 by default), downloads remote OpenAPI specifications at startup, and sends HTTP requests to the target API.
- Files
- Reads a local OpenAPI specification file relative to the application directory when configured with a file path.
- Secrets
- Reads API keys and authentication settings from environment variables (such as Enframe__ApiKey) and forwards them or client bearer tokens to the target API.
Findings
-
HighMCP server runs unauthenticated unless the OpenAPI spec declares OAuth2 scopes
Client authentication on the MCP HTTP endpoint is only enabled when OpenApiTools.ResolveTokenAuth returns a non-null result, which requires the OpenAPI spec to declare an oauth2 security scheme containing at least one scope. When wrapping APIs that use only apiKey authentication, HTTP bearer tokens, OpenID Connect without a separate oauth2 scheme, or no security—even if the operator explicitly configures Enframe:Authority—the MCP server runs without authentication and allows any network caller to invoke tools using the server's configured Enframe:ApiKey.
Fix: Enable authentication whenever Enframe:Authority is configured regardless of the target spec's security schemes, and require an explicit opt-in flag before serving MCP endpoints without authentication, especially when Enframe:ApiKey is set.
-
MediumPath parameter dot-segment traversal in target API requests
src/Enframe.Mcp/OpenApiTool.cs:101
Path parameters are inserted into the route template using Uri.EscapeDataString, which leaves '.' and '..' unescaped because '.' is an unreserved URI character. If an attacker supplies '.' or '..' in a path parameter via prompt injection, the constructed request URI resolves those dot-segments and traverses to parent paths on the target API using the server's credentials.
Fix: Reject path parameter values that are '.' or '..' (or empty), or explicitly percent-encode '.' as '%2E' when substituting path segments.
-
MediumAutomatic HTTP redirects can leak configured API keys to external hosts
The SocketsHttpHandler used for outbound target API calls leaves AllowAutoRedirect set to its default value of true. When an operation authenticates with AuthMode.ApiKey, OpenApiTool attaches the secret key in a custom header (such as Ocp-Apim-Subscription-Key). Unlike the standard Authorization header, custom headers are not stripped by SocketsHttpHandler across cross-origin 3xx redirects, so a redirect response from the target API will forward the secret API key to the redirect target.
Fix: Set AllowAutoRedirect = false on the SocketsHttpHandler configured for the 'target-api' HttpClient.
-
LowUnbounded upstream response buffering can exhaust memory
src/Enframe.Mcp/OpenApiTool.cs:197
Although structured content parsing is skipped for responses larger than 256 KB, BuildResultAsync still buffers the entire HTTP response body into memory with ReadAsByteArrayAsync and decodes it into a full string. A large response from the target API can cause excessive memory allocation and denial of service.
Fix: Set MaxResponseContentBufferSize on the HttpClient or read the response stream with a bounded byte limit.
-
LowContainer port published to all network interfaces in documentation examples
The documented podman run commands use
-p 8080:8080, which binds port 8080 on all host network interfaces (0.0.0.0). Because Enframe only requires MCP client bearer authentication when the OpenAPI spec declares an OAuth2 scheme with an identifiable authority, following this command for an API that uses onlyEnframe__ApiKey(or no authentication) exposes the MCP endpoint and its configured API key to other machines on the local network.Fix: Bind the published container port to the loopback interface by default in documentation examples (
-p 127.0.0.1:8080:8080).