Sep 15, 2026·9 min read·4 visits
Unauthenticated remote attackers can bypass Same-Origin Policy via DNS Rebinding to execute commands and access data through the local GitLab MCP server due to missing Host and Origin header validation.
A critical security vulnerability has been identified in the @zereight/mcp-gitlab implementation of the Model Context Protocol (MCP) server. Prior to version 2.1.30, the server lacks HTTP Host and Origin header validation on its Streamable HTTP transport interface (/mcp). This security omission permits remote attackers to bypass the Same-Origin Policy (SOP) via a DNS Rebinding attack. Under this vector, an attacker can route malicious API requests to the victim's local or internal MCP server, thereby gaining unauthorized control over the victim's GitLab account and resources.
The Model Context Protocol (MCP) defines an open standard for secure bidirectional communication between local Large Language Model (LLM) applications and remote or local data sources, systems, and APIs. In the context of the @zereight/mcp-gitlab server, this integration allows developer agents to query, create, or alter repositories, branch setups, pull requests, issues, and pipelines. To facilitate browser-based tool interactions or integration within local containerized orchestrations, the @zereight/mcp-gitlab server implements a Streamable HTTP transport endpoint located at /mcp. This HTTP listener executes locally on a loopback interface, commonly on a user-specified port or default range, and operates using the target user's local operating system identity and GitLab credentials.
Historically, developer tools operating on loopback interfaces have relied upon the browser's Same-Origin Policy (SOP) to block malicious external websites from querying local socket endpoints. However, because the SOP restricts access based on the hostname of the origin rather than the underlying network socket's IP destination, local endpoints must explicitly validate incoming routing metadata. In versions of @zereight/mcp-gitlab prior to 2.1.30, the Express-based Streamable HTTP server fails to perform verification checks on the standard Host and Origin HTTP request headers. This failure exposes a critical attack surface, as any HTTP client capable of reaching the TCP socket can interact with the API interface.
The class of this flaw is classified under CWE-350 (Reliance on Reverse DNS Resolution for a Security-Critical Action), specifically materializing as a DNS Rebinding vulnerability. An attacker can leverage this flaw by executing arbitrary code inside the context of a victim's web browser, bridging the boundary from an untrusted public domain to the victim's local loopback domain. Because the MCP server stores sensitive, high-privilege credentials—such as personal access tokens, job tokens, or active authentication cookies—the target's GitLab instance can be completely compromised by an unauthenticated remote adversary. This threat vector bypasses firewall boundaries and physical segmentations by abusing the victim's browser as a trusted network proxy.
The fundamental technical flaw in the Streamable HTTP transport implementation lies in the lack of request-filtering middleware at the HTTP routing boundary. When the application initializes its server interface using the Express framework, it configures routes such as /mcp without binding any policy check to verify if the requested Host header aligns with the intended deployment address. In a standard web browser context, the Same-Origin Policy prevents an active script executing under https://attacker.com from dispatching a request to http://localhost:3002 and reading the response. However, the browser delegates name resolution to the underlying DNS subsystem, creating a synchronization gap that can be exploited via DNS Rebinding.
In a typical DNS Rebinding scenario, an attacker provisions an authoritative nameserver for a domain they control, such as rebinder.attacker.test. The nameserver is configured with a Time-To-Live (TTL) value of 0 seconds to prevent caching. When the victim browser navigates to the attacker's domain, the authoritative server returns the actual IP address of the attacker's web server. The browser loads the malicious payload page, establishes an origin context of http://rebinder.attacker.test, and begins executing malicious JavaScript. The malicious script then initiates a background XMLHttp or Fetch request back to its parent domain, pointing to the /mcp endpoint.
As the DNS TTL is set to 0, the browser must re-resolve rebinder.attacker.test to process the new connection. At this step, the attacker's DNS server answers with the loopback IP address 127.0.0.1. The browser, strictly adhering to the name-based SOP, permits the request because the origin hostname rebinder.attacker.test remains unchanged. The browser dispatches the HTTP request directly to 127.0.0.1:3002. The request arrives at the local @zereight/mcp-gitlab server, bearing the headers Host: rebinder.attacker.test and Origin: http://rebinder.attacker.test. Prior to the implementation of the patch, the server processed this payload without validation, interpreting the request as a valid client connection and executing the embedded JSON-RPC payload.
The vulnerability was resolved in Pull Request #555 with the commit 52207c6f5c0e7a39e9235d491225edbb562a0290. The fix introduces an active validation middleware function, requireMcpHostAndOrigin, inside the primary server configuration file. This middleware extracts, normalizes, and compares the incoming HTTP headers against an explicitly parsed and configured allowlist of hosts and origins.
Let us analyze the critical validation function implemented to protect the server:
function requireMcpHostAndOrigin(req: Request, res: Response, next: NextFunction) {
const host = toAllowedMcpHost(req.headers.host || "");
if (
!host ||
(!isLoopbackMcpHost(host) && !MCP_DNS_REBINDING_PROTECTION.allowedHosts.includes(host))
) {
res.status(403).json({
error: "Host header is not allowed",
hint: "Set MCP_SERVER_URL or MCP_ALLOWED_HOSTS for non-loopback /mcp hosts.",
});
return;
}
const originHeader = req.headers.origin;
if (originHeader) {
const origin = toAllowedMcpOrigin(Array.isArray(originHeader) ? originHeader[0] : originHeader);
if (
!origin ||
(!isLoopbackMcpOrigin(origin) &&
!MCP_DNS_REBINDING_PROTECTION.allowedOrigins.includes(origin))
) {
res.status(403).json({
error: "Origin header is not allowed",
hint: "Set MCP_SERVER_URL or MCP_ALLOWED_ORIGINS for non-loopback browser origins.",
});
return;
}
}
next();
}The middleware intercepts incoming requests to /mcp prior to any JSON parsing or JSON-RPC handling. The logic utilizes Node's WHATWG URL parser to extract hostnames safely, which protects against URL parsing bypasses where characters like @ or special port indicators are manipulated. It establishes a loopback exception where any requests routing to localhost, 127.0.0.1, or [::1] on any port are automatically approved. This exception is secure because an attacker executing a DNS Rebinding attack must point the browser to their arbitrary domain, which forces the Host header to hold the attacker's domain value rather than a loopback string. The patch is applied to the application route hierarchy as follows:
app.use("/mcp", requireMcpHostAndOrigin);
app.use(express.json());This mounting order ensures that validation occurs before JSON parsing, which prevents CPU cycles from being consumed on unauthenticated payloads. If either the Host or Origin check fails, the middleware aborts the request pipeline immediately, returning an HTTP 403 Forbidden status.
Exploitation of CVE-2026-61568 is highly reliable and relies on a target user running a vulnerable version of the server locally while browsing the web. The attacker initiates the exploitation cycle by registering a target domain and configuring a custom authoritative DNS server capable of dynamically toggling A record responses. Once the victim is induced to visit the attacker-controlled webpage, the malicious site serves a payload designed to loop requests.
The payload script implements a standard asynchronous loop that sends HTTP POST requests containing MCP initialization payloads to the target local port (typically standard development ports). The request format resembles the following JSON-RPC schema:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": {
"name": "malicious-agent",
"version": "1.0.0"
}
}
}The integration test suite located in test/streamable-http-dns-rebinding.test.ts provides a clear proof-of-concept. It spins up the server dynamically and sends requests with forged Host and Origin headers to simulate the DNS Rebinding behavior. The tests assert that the patched server rejects headers containing domains such as attacker.example.test with an HTTP 403 response, while still allowing legitimate remapped Docker ports originating from loopback hosts. By evaluating this test, security engineers can confirm that the mitigation successfully breaks the DNS Rebinding vector without impairing valid developer configurations.
The security impact of CVE-2026-61568 is critical, as reflected by its CVSS 3.1 base score of 9.6. Because the MCP server operates in a scope that bridges the local browser interface to the corporate GitLab API, the vulnerability results in a Change (S:C) of security boundaries. This allows an attacker to leverage the victim's authorization state on the GitLab server.
If the victim possesses administrative access or access to proprietary codebases, the impact translates to a complete loss of confidentiality and integrity. The malicious JavaScript payload running in the browser can execute JSON-RPC commands on the local MCP server to read raw source code repositories, download sensitive environment configuration files, manipulate pipeline variables, and inject malicious commits directly into protected branches. Furthermore, the attacker can leverage the server to approve merge requests, trigger deployment pipelines to expose production secrets, or delete critical repository data, which completely compromises the availability of the organization's DevOps infrastructure.
The attack vector is purely remote and requires no active privileges on the part of the attacker, though it requires minimal user interaction to entice the victim to load the initial malicious website. Because the vulnerability targets developers who frequently run local tools with active, high-privilege access keys, a successful compromise can serve as a vector for supply chain attacks against downstream software products.
To completely remediate CVE-2026-61568, administrators and developers must update @zereight/mcp-gitlab to version 2.1.30 or higher immediately. This update enforces the Host and Origin validation middleware by default. The update can be performed through npm or equivalent package managers using the command:
npm install @zereight/mcp-gitlab@latestIf the server must be deployed in non-loopback topologies—such as behind a reverse proxy, inside an orchestrator network like Kubernetes, or on an internal corporate network address—administrators must configure explicit environmental configurations to allow authorized traffic. The server reads these configurations from environment variables at startup. To declare these safe domains, define MCP_SERVER_URL with the server's public URL, or define MCP_ALLOWED_HOSTS and MCP_ALLOWED_ORIGINS with comma-separated lists of acceptable hosts and origins. For example:
export MCP_SERVER_URL="https://mcp.internal.net"
export MCP_ALLOWED_HOSTS="mcp.internal.net,mcp.internal:3002"
export MCP_ALLOWED_ORIGINS="https://mcp.internal.net,http://localhost:3000"For systems that cannot be immediately updated, temporary workarounds include blocking access to the MCP server port from external network interfaces using local firewall rules (e.g., binding the application socket strictly to 127.0.0.1 rather than 0.0.0.0) and restricting developers from visiting untrusted external websites while the local server is active.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
@zereight/mcp-gitlab zereight | < 2.1.30 | 2.1.30 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-350 |
| Attack Vector | Network |
| CVSS Score | 9.6 |
| EPSS Score | Not Available |
| Impact | Complete Confidentiality, Integrity, and Availability Loss |
| Exploit Status | poc |
| KEV Status | Not Listed |
The software relies on reverse DNS resolution to perform a security-critical action, which can allow attackers to bypass security checks.
A constellation of five distinct security flaws (F1 through F5) in `@zereight/mcp-gitlab` prior to version 2.1.30 allows unauthenticated remote access, read-only policy bypasses, DNS rebinding, and denial-of-service via session exhaustion.
A critical Server-Side Request Forgery (SSRF) vulnerability in @zereight/mcp-gitlab allows attackers to leak sensitive GitLab Private-Tokens by supplying an arbitrary external hostname via the X-GitLab-API-URL header when dynamic routing is enabled.
A critical memory leak vulnerability exists in the server-side DigestAuth middleware of the http4s library. Due to a logical inversion in the stale-nonce clean-up routine, the internal cache fails to evict stale nonces while prematurely purging fresh ones. Unauthenticated remote attackers can exploit this behavior by repeatedly prompting the server for authentication challenges, leading to unbounded memory consumption and application crashes via a java.lang.OutOfMemoryError.
An incomplete security fix in Shopper prior to version 2.9.2 exposes a Broken Function Level Authorization (BFLA) vulnerability in the Media component. Low-privileged administrative users with 'browse_products' permissions can bypass role-based access control policies to execute the 'store' action and modify product media.
A critical authorization bypass and insecure direct object reference (IDOR) vulnerability was discovered in Shopper, a Headless e-commerce Admin Panel. Due to missing authorization chains on table actions and the lack of a locked property on the collection state model, authenticated low-privilege staff can detach products from arbitrary collections.
CVE-2026-59973 is a high-severity Server-Side Request Forgery (SSRF) vulnerability in FrontMCP and its underlying OpenAPI parsing library, mcp-from-openapi. The flaw allows authenticated attackers capable of importing or configuring OpenAPI specifications to bypass string-based hostname filtering mechanisms. By employing DNS wildcard loopbacks, HTTP redirects, or IPv4-mapped IPv6 address formatting, attackers can coerce the application into sending HTTP requests to internal networks, loopback adapters, and cloud metadata environments.