VulnWatch VulnWatch
← Back to dashboard
Critical github · GHSA-vmp7-252j-cwp7

@zereight/mcp-gitlab: DNS rebinding reaches local Streamable HTTP MCP transport

Published Sep 15, 2026 CVSS 9.6

@zereight/mcp-gitlab exposes its Streamable HTTP MCP endpoint without an effective Host or Origin allowlist. A malicious web page can use DNS rebinding to route browser requests to a victim's local MCP listener while preserving an attacker-controlled Host and Origin. The server accepts those headers and reaches the MCP initialization path instead of rejecting the request at the HTTP boundary.

This is CWE-350, Reliance on Reverse DNS Resolution for a Security-Critical Action. The affected package is @zereight/mcp-gitlab version 2.1.18 at commit 74a8c834424ff557ad8bc6f225e4dc5acf80aa13.

The vulnerable transport setup is in index.ts. Express JSON parsing is installed globally before any MCP route-level Host or Origin allowlist:

// index.ts:12077
app.use(express.json());

registerDownloadProxy(app);

The Streamable HTTP transport is then created without the SDK DNS-rebinding controls:

// index.ts:12375
transport = new StreamableHTTPServerTransport({
  sessionIdGenerator: () => randomUUID(),
  onsessioninitialized: (newSessionId: string) => {
    streamableTransports[newSessionId] = transport;
    metrics.totalSessions++;
    metrics.activeSessions++;
  },
});

The transport constructor does not set enableDnsRebindingProtection, allowedHosts, or allowedOrigins. The server also does not add an Express middleware that rejects unexpected Host or Origin headers before /mcp.

The default host is loopback, which is the exact target DNS rebinding attacks are designed to reach:

// config.ts:192
export const HOST = getConfig("host", "HOST") || "127.0.0.1";

// config.ts:196
export const PORT = _intEnv("PORT", "port", _PORT_DEFAULT);

The README documents Streamable HTTP as a supported transport for modern remote deployments and documents REMOTE_AUTHORIZATION=true for multi-user HTTP deployments. In that mode, unauthenticated tools/list and material GitLab API tool calls are blocked by token checks. The Host/Origin defect is still present at the browser boundary: the server accepts attacker-controlled browser-origin headers and processes the MCP initialize request instead of rejecting the connection as cross-origin localhost access.

Proof of concept

The following reproduction uses a fake GitLab API with planted data. It proves the HTTP boundary failure and the token boundary separately:

  • no-token initialize succeeds with attacker-controlled Host and Origin;
  • no-token tools/list is rejected with 401;
  • the same forged-origin flow with a planted Private-Token lists tools and calls list_project_variables;
  • the fake GitLab API records the forwarded token and returns a planted fake project variable.

Start the fake GitLab API:

python3 -

Affected AI Products

mcp server
Get the weekly digest. Every Monday: top AI security stories of the week. Free.