← Back to Feed CACHED · 2026-09-12 08:09:29 · CACHE_KEY CVE-2026-85706
CVE-2026-85706 · CWE-22 · Disclosed 2026-09-12

GitLab has remediated an issue in GitLab CE/EE affecting all versions from 18.7 before 19.1.8

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

Someone left the filing cabinet unlocked in the room that holds every deployment key, runner token, and database password your org owns

CVE-2026-85706 is a path traversal vulnerability in the GitLab CE/EE repository commits API (/api/v4/projects/{id}/repository/commits/). By sending a crafted HTTP POST request with a manipulated file.path parameter, an unauthenticated attacker can read arbitrary files from the underlying server — configuration files, SSH keys, CI/CD secrets, database credentials, and anything else the git process user can access. The flaw is rooted in improper path confinement combined with missing authentication enforcement on the affected endpoint. All self-managed GitLab CE/EE versions from 18.7 through 19.1.7, 19.2.0–19.2.5, and 19.3.0–19.3.1 are vulnerable. Fixed versions are 19.1.8, 19.2.6, and 19.3.2, released September 10, 2026.

The vendor CVSS of 10.0 is completely justified and noisgate agrees. There is zero friction in this chain: no authentication, no user interaction, no elevated privileges, network-reachable from the internet in the majority of self-managed deployments. watchTowr confirmed active exploitation probes began at 06:00 UTC on September 11 — less than 24 hours after the patch shipped — and CISA added it to the KEV catalog the same week. The affected component is a CI/CD server that by definition holds source code, secrets, and deployment credentials. This is a supply-chain-class vulnerability and the 10.0 is earned.

"Unauthenticated file read on your CI/CD brain. Patch now or lose your secrets."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify exposed GitLab instance

The attacker scans the internet for self-managed GitLab instances on standard web ports (80/443). CyCognito identified over 20,000 reachable instances via Shodan and Censys. The GitLab login page and API versioning headers trivially fingerprint the product and version.
Conditions required:
  • Target runs self-managed GitLab CE/EE on a network-reachable port
Where this breaks in practice:
  • GitLab.com SaaS users are not affected — only self-managed instances
Detection/coverage: Shodan/Censys/FOFA queries for GitLab headers; GreyNoise tags for GitLab scanning activity
STEP 02

Send crafted commits API request

The attacker sends a single unauthenticated HTTP POST to /api/v4/projects/{id}/repository/commits/ with a file.path parameter containing path traversal sequences (e.g., ../../../etc/passwd). No valid credentials, session tokens, or API keys are required. The request complexity is trivially low — a single curl command suffices.
Conditions required:
  • GitLab version in vulnerable range (18.7–19.1.7, 19.2.0–19.2.5, 19.3.0–19.3.1)
  • The commits API endpoint is reachable (default configuration)
Where this breaks in practice:
  • None — the endpoint is enabled by default and requires no authentication
Detection/coverage: WAF rules matching path traversal patterns in POST bodies to /api/v4/projects/*/repository/commits/; log review for POST requests to this URI containing file.path
STEP 03

Read sensitive server files

The GitLab server returns the contents of the requested file in the API response. The attacker targets high-value files: /etc/gitlab/gitlab.rb (master config with DB passwords, SMTP creds, LDAP bind passwords), /etc/gitlab/gitlab-secrets.json (encryption keys for CI/CD variables, runner tokens, two-factor secrets), SSH host keys, and /opt/gitlab/embedded/service/gitlab-rails/.env. A single successful request can yield dozens of plaintext secrets.
Conditions required:
  • The GitLab process user (typically git) has read access to the target file
Where this breaks in practice:
  • File permissions on hardened hosts may limit reads — but default GitLab Omnibus installs give the git user broad read access to config files
Detection/coverage: File integrity monitoring (FIM) won't fire — this is a read, not a write. Detection relies on network-layer log analysis of the commits API.
STEP 04

Pivot via stolen secrets

With gitlab-secrets.json and gitlab.rb in hand, the attacker can decrypt all CI/CD variables stored in the database (which contain deploy keys, cloud API tokens, container registry credentials), impersonate runners, forge session cookies, and pivot into production infrastructure. This is a supply-chain compromise: the attacker can inject code into pipelines, push backdoored artifacts, or exfiltrate proprietary source code.
Conditions required:
  • Stolen secrets are valid and not rotated
Where this breaks in practice:
  • Organizations that rotate secrets frequently or use external secret managers (Vault, AWS Secrets Manager) with short-lived tokens reduce blast radius — but most self-managed GitLab deployments store secrets directly in CI/CD variables
Detection/coverage: Anomalous runner registrations, unexpected pipeline executions, or API calls from unfamiliar IPs post-compromise
03 · Intelligence Metadata

The supporting signals.

In-the-Wild StatusActively exploited. watchTowr confirmed behavioral probes starting 06:00 UTC September 11, 2026 — less than 24 hours after patch release. CISA added to KEV catalog.
KEV StatusListed. Added to CISA Known Exploited Vulnerabilities catalog, September 2026.
Proof-of-ConceptNo public PoC repository identified, but watchTowr confirms attackers have reverse-engineered and reproduced the vulnerability based on honeypot telemetry. Exploitation is trivial (single HTTP request).
EPSS ScoreNot yet published (CVE disclosed September 12, 2026). Given KEV listing and active exploitation, expect ≥ 0.95 (top 1%) once scored.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N — Network-accessible, no auth, no interaction, changed scope, high confidentiality and integrity impact. The 10.0 is the maximum possible score.
Affected VersionsGitLab CE/EE 18.7 – 19.1.7, 19.2.0 – 19.2.5, 19.3.0 – 19.3.1
Fixed Versions19.1.8, 19.2.6, 19.3.2 (released September 10, 2026)
Exposure DataCyCognito reports >20,000 self-managed GitLab instances reachable on standard web ports (Shodan/Censys). Approximately 1,400 remain on vulnerable versions days after patch release.
Disclosure DateSeptember 10, 2026 (patch); September 11–12, 2026 (public advisory and KEV listing)
Reporting ResearcherDiscovered via GitLab's bug bounty program; specific researcher not publicly credited.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to CRITICAL (10.0/10)

The single most decisive factor is the supply-chain role multiplier: GitLab is canonically a CI/CD server whose compromise yields source code, deployment secrets, runner impersonation, and pipeline injection — the blast radius is fleet-scale and supply-chain-scale by definition. Active KEV-listed exploitation with zero authentication requirements and trivial attack complexity leaves no room for downgrade.

HIGH Vulnerability severity and exploitability assessment
HIGH Active exploitation status (KEV + watchTowr honeypot data)
MEDIUM Exact EPSS score (not yet published, estimated based on profile)

Why this verdict

  • Zero authentication barrier: The commits API endpoint requires no credentials, tokens, or session — a single curl command from the internet exploits it. No friction to discount.
  • Role multiplier — CI/CD supply-chain server: GitLab self-managed is, by definition, a supply-chain-critical component. ≥90% of self-managed GitLab installations serve as the primary CI/CD platform for their organization. Compromise yields source code, CI/CD secrets, deploy keys, runner tokens, and pipeline injection capability. Blast radius: supply-chain-scale. This sets the verdict floor at CRITICAL.
  • Active exploitation with KEV listing: Attackers reverse-engineered the patch within 24 hours. CISA KEV confirms in-the-wild exploitation. Over 20,000 instances are internet-reachable per Shodan/Censys, with ~1,400 still running vulnerable versions.
  • Trivial exploit complexity: No public PoC needed — the attack is a single HTTP POST with path traversal in file.path. Any script kiddie with a curl one-liner can exfiltrate gitlab-secrets.json.

Why not higher?

A 10.0 is the maximum CVSS score. There is no higher severity bucket than CRITICAL. The vendor assessment is accurate and noisgate has no room to upgrade further.

Why not lower?

Every downgrade factor was evaluated and none apply. The attack is unauthenticated (no auth friction), network-reachable (no internal-only friction), low complexity (no chaining friction), and the target component is canonically a high-value CI/CD server where ≥90% of installs occupy a supply-chain-critical role. The role-multiplier floor rule locks this at CRITICAL regardless. Active KEV exploitation removes any theoretical-only discount. There is no legitimate basis to downgrade.

05 · Compensating Control

What to do — in priority order.

  1. Block unauthenticated access to the commits API at the reverse proxy or WAF — Add a rule to your reverse proxy (nginx, HAProxy, Cloudflare, AWS ALB) blocking unauthenticated POST requests to /api/v4/projects/*/repository/commits/ immediately. This is the fastest mitigation if you cannot patch within hours. Deploy within the noisgate mitigation SLA of ≤ 3 days for CRITICAL, though given active exploitation, deploy within hours.
  2. Restrict GitLab to VPN or zero-trust access only — If your GitLab instance is internet-facing, place it behind a VPN, ZTNA gateway, or IP allowlist immediately. This eliminates the unauthenticated remote attack vector entirely. Given KEV status, do this today.
  3. Rotate all secrets stored in GitLab — After patching, rotate all CI/CD variables, runner registration tokens, deploy keys, SSH keys, SMTP credentials, LDAP bind passwords, and the Rails secret key base in gitlab-secrets.json. Assume compromise if the instance was internet-facing and unpatched between September 10–12. Complete within 72 hours of patching.
  4. Audit logs for exploitation indicators — Review GitLab production logs (gitlab-rails/production.log) for HTTP POST requests to /api/v4/projects/{id}/repository/commits/ containing file.path parameters with traversal sequences (../). Forward to your SIEM for retrospective analysis from September 10 onward.
  5. Apply the vendor patch — Upgrade to GitLab 19.3.2, 19.2.6, or 19.1.8 per the noisgate remediation SLA of ≤ 90 days for CRITICAL — though given active exploitation, patch immediately, within hours if possible.
What doesn't work
  • Network segmentation alone does not help if GitLab must remain accessible to developers over the internet — the attack requires only standard HTTPS access to the API, which is the same port developers use.
  • GitLab's built-in rate limiting does not mitigate this — a single request is sufficient for exploitation; rate limiting only slows bulk exfiltration.
  • File integrity monitoring (FIM) will not detect this attack because it is a file *read*, not a file write or modification — FIM agents never fire.
  • EDR on the GitLab host is unlikely to alert on the git user reading files through the normal Rails application process — the file access looks legitimate at the OS level.
06 · Verification

Crowdsourced verification payload.

Run this script on the GitLab server itself (or from any host with curl access to the GitLab instance). Invoke as: bash check_cve_2026_85706.sh https://gitlab.example.com. No special privileges required — it checks the installed GitLab version via the public API.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_85706.sh — Check GitLab for CVE-2026-85706 (path traversal in commits API)
# Usage: bash check_cve_2026_85706.sh <GITLAB_URL>
# Exit codes: 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN

set -euo pipefail

GITLAB_URL="${1:?Usage: $0 <GITLAB_URL>}"
GITLAB_URL="${GITLAB_URL%/}"

echo "[*] Checking GitLab version at ${GITLAB_URL}..."

# Fetch version from the public metadata endpoint
VERSION_JSON=$(curl -sk --max-time 10 "${GITLAB_URL}/api/v4/version" 2>/dev/null || true)

if [ -z "$VERSION_JSON" ]; then
  # Try the unauthenticated metadata endpoint
  VERSION_JSON=$(curl -sk --max-time 10 "${GITLAB_URL}/api/v4/metadata" 2>/dev/null || true)
fi

if [ -z "$VERSION_JSON" ]; then
  echo "[!] Could not retrieve GitLab version. The API may require authentication."
  echo "[*] Trying to parse version from the login page..."
  LOGIN_PAGE=$(curl -sk --max-time 10 "${GITLAB_URL}/users/sign_in" 2>/dev/null || true)
  VERSION=$(echo "$LOGIN_PAGE" | grep -oP 'GitLab (Community|Enterprise) Edition \K[0-9]+\.[0-9]+\.[0-9]+' | head -1)
  if [ -z "$VERSION" ]; then
    echo "UNKNOWN — could not determine GitLab version"
    exit 2
  fi
else
  VERSION=$(echo "$VERSION_JSON" | grep -oP '"version"\s*:\s*"\K[0-9]+\.[0-9]+\.[0-9]+' | head -1)
fi

if [ -z "$VERSION" ]; then
  echo "UNKNOWN — could not parse GitLab version"
  exit 2
fi

echo "[*] Detected GitLab version: ${VERSION}"

MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)

VULNERABLE=0

# Affected: 18.7+ through 19.1.7, 19.2.0-19.2.5, 19.3.0-19.3.1
if [ "$MAJOR" -eq 18 ] && [ "$MINOR" -ge 7 ]; then
  VULNERABLE=1
elif [ "$MAJOR" -eq 19 ]; then
  if [ "$MINOR" -eq 0 ]; then
    VULNERABLE=1
  elif [ "$MINOR" -eq 1 ] && [ "$PATCH" -lt 8 ]; then
    VULNERABLE=1
  elif [ "$MINOR" -eq 2 ] && [ "$PATCH" -lt 6 ]; then
    VULNERABLE=1
  elif [ "$MINOR" -eq 3 ] && [ "$PATCH" -lt 2 ]; then
    VULNERABLE=1
  fi
fi

if [ "$VULNERABLE" -eq 1 ]; then
  echo "VULNERABLE — GitLab ${VERSION} is affected by CVE-2026-85706"
  echo "[!] Upgrade immediately to 19.1.8, 19.2.6, or 19.3.2"
  exit 1
else
  echo "PATCHED — GitLab ${VERSION} is not in the affected version range"
  exit 0
fi
07 · Bottom Line

If you remember one thing.

TL;DR
This is a drop-everything vulnerability. If you run self-managed GitLab CE/EE on any version from 18.7 through 19.3.1, you are exposed to unauthenticated arbitrary file read that is actively being exploited in the wild and is KEV-listed by CISA. Per the noisgate mitigation SLA for CRITICAL, compensating controls (WAF block on the commits API or VPN restriction) must be in place within 3 days — but given confirmed active exploitation, treat this as an immediate, same-day emergency. Patch to 19.1.8, 19.2.6, or 19.3.2 per the noisgate remediation SLA of ≤ 90 days, though realistically you should patch within hours, not days. After patching, assume compromise if the instance was internet-facing during September 10–12: rotate every secret stored in GitLab (CI/CD variables, runner tokens, deploy keys, gitlab-secrets.json), audit logs for exploitation indicators, and notify downstream teams whose pipelines or credentials may have been exposed.

Sources

  1. Horizon3 – CVE-2026-85706 Technical Analysis
  2. watchTowr – Rapid Reaction: GitLab Critical Path Traversal
  3. BleepingComputer – GitLab Urges Users to Patch Max Severity Flaw
  4. SecurityWeek – GitLab Vulnerability Exploited One Day After Disclosure
  5. CyberScoop – GitLab's Critical Flaw Draws Internet-Wide Probes
  6. CISA – GitLab Path Traversal Vulnerability Exploited in Attacks
  7. The Hacker News – GitLab CVSS 10 File-Read Flaw Draws In-the-Wild Probes
  8. SecurityOnline – GitLab Vulnerabilities CVE-2026-85706 CVSS 10.0
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.