← Blog · · df00tech

SSRF in @zereight/mcp-gitlab Lets Attackers Steal GitLab Tokens via X-GitLab-API-URL Header

breaking ghsa npm CVE-2026-61559

A GitHub Security Advisory (GHSA-2h44-8472-frjj, tracked as CVE-2026-61559) discloses a high-severity server-side request forgery vulnerability in zereight/gitlab-mcp, a GitLab MCP server distributed as @zereight/mcp-gitlab on npm. The advisory reports CVSS v3.1 8.5, and a public proof-of-concept is available. No patched version exists at time of report.

What Was Reported

When the server is run with ENABLE_DYNAMIC_API_URL=true, it reads an attacker-controllable X-GitLab-API-URL HTTP header and uses it as the base URL for outbound GitLab API calls made during that request. The server only checks that the header is a syntactically valid URL — it applies no hostname allowlist. Per the advisory, this affects two code paths: the SSE handler and the Streamable HTTP handler's parseAuthHeaders logic. Because the server attaches the caller's Private-Token to every outbound fetch, redirecting the base URL to an attacker-controlled host causes the victim's GitLab token to be delivered directly to that host in the request headers.

Why It Matters for Defenders

Any deployment running this MCP server with ENABLE_DYNAMIC_API_URL=true — the documented mode for supporting self-hosted GitLab instances, and required for multi-user deployments using REMOTE_AUTHORIZATION=true — is exposed to credential theft in a single request, without the attacker needing any prior access to the victim's token. A stolen GitLab Personal Access Token or CI/CD job token grants the attacker's controlled host full API access at the victim's permission level: reading repositories, issues, merge requests, and CI/CD variables/secrets, plus write access to push code, alter pipelines, and rotate CI/CD variables. The advisory notes that a prior fix (PR #453) added a startup guard restricting static-token use on the Streamable HTTP transport, but that guard does not validate X-GitLab-API-URL or touch the vulnerable code path — the sink remains reachable in the documented multi-user mode.

What Defenders Should Do Now

  • Inventory any use of zereight/gitlab-mcp / @zereight/mcp-gitlab in your environment, especially deployments with ENABLE_DYNAMIC_API_URL=true or REMOTE_AUTHORIZATION=true.
  • Until a patch ships, consider disabling ENABLE_DYNAMIC_API_URL entirely, or place a reverse proxy/gateway in front of the MCP server that strips or validates the X-GitLab-API-URL header against a known-good hostname allowlist.
  • Hunt for outbound connections from hosts running this MCP server to unexpected or non-GitLab destinations, particularly around the time of any MCP tool-call activity.
  • Review GitLab audit logs for API access patterns inconsistent with expected server-side automation, and consider rotating tokens used by any exposed instance.
  • If self-hosting GitLab and relying on this feature, track the upstream repository for a fix that adds hostname allowlisting as described in the advisory's remediation guidance.

Developing Intel

This is a freshly disclosed advisory with a public proof-of-concept and no vendor patch available as of publication. Details may evolve as the maintainer responds. For the full technical writeup, PoC, and remediation code sample, see the original advisory: GHSA-2h44-8472-frjj.

Get new detections in your inbox

New ATT&CK coverage plus CISA KEV / CVE detection rules, roughly weekly. No spam, unsubscribe anytime.