← Back to Feed CACHED · 2026-09-12 08:15:00 · CACHE_KEY CVE-2026-87719
CVE-2026-87719 · CWE-502 · Disclosed 2026-09-12

GitLab has remediated an issue in GitLab EE affecting all versions from 18.3 before 19.1.8

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

Like leaving a master key inside a vending machine that only premium subscribers can use

CVE-2026-87719 is an insecure deserialization flaw (CWE-502) in GitLab EE's GraphQL subscription serializer. An authenticated user who has Duo Chat access can craft a malicious GraphQL subscription argument that bypasses serialization controls and triggers unauthorized server-side object lookup. The result: the attacker obtains Advanced Search (Elasticsearch/OpenSearch) instance configurations and sensitive credentials — connection strings, passwords, API keys — for the search backend. Affected versions span GitLab EE 18.3 through 19.1.7, 19.2.0–19.2.5, and 19.3.0–19.3.1. Fixed in 19.1.8, 19.2.6, and 19.3.2 (released September 10, 2026). Reported by kyyblin via HackerOne.

GitLab scored this CVSS 9.9 CRITICAL with Scope Changed and all-high CIA impact. That vector overstates the real-world risk for most deployments. The 9.9 implies near-RCE with scope escape, but the documented impact is credential disclosure — specifically Advanced Search backend credentials. That's serious, but it's not arbitrary code execution on the GitLab host. More importantly, the attack requires *two* gates: (1) a valid authenticated session, and (2) Duo Chat access, which demands GitLab EE with a Premium/Ultimate license plus a Duo add-on (Core, Pro, or Enterprise). Many EE installations have not purchased or enabled Duo, and CE installations are entirely unaffected. The vendor severity is therefore inflated by roughly one full tier for the majority of self-managed deployments.

"Duo Chat gate shrinks the blast radius, but stolen Elasticsearch creds can pivot deep."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Obtain authenticated GitLab session

The attacker needs a valid user account on the target GitLab EE instance. On internet-facing instances that allow self-registration (or where the attacker has compromised any low-privilege credential), this is trivial. On locked-down internal instances, this requires prior compromise or insider access.
Conditions required:
  • Valid GitLab EE user account
  • Network access to the GitLab instance (internet or internal)
Where this breaks in practice:
  • Many enterprises disable public self-registration on self-managed GitLab
  • Internal-only instances require pre-existing network access
Detection/coverage: Authentication logs; anomalous new account creation alerts
STEP 02

Confirm Duo Chat entitlement

The attacker's account must belong to a group with an active GitLab Duo add-on (Core, Pro, or Enterprise) on a Premium or Ultimate license. By default, any user in such a group can access Duo Chat unless the duo_chat_requires_licensed_seat feature flag restricts it further. The attacker can verify access by attempting to invoke the Duo Chat interface.
Conditions required:
  • GitLab EE instance has Duo add-on enabled
  • User belongs to a Premium/Ultimate group with Duo access
Where this breaks in practice:
  • Duo is a paid add-on — not all EE instances purchase it
  • Organizations can restrict Duo Chat to licensed seats only via feature flag
  • GitLab CE installations (a large share of self-managed) are entirely unaffected
Detection/coverage: Duo Chat usage audit logs; license assignment reports
STEP 03

Craft malicious GraphQL subscription

The attacker constructs a specially crafted GraphQL subscription argument designed to bypass the serializer's expected deserialization path. This triggers an unauthorized server-side object lookup that resolves internal objects the user should not be able to read. No public PoC has been identified as of disclosure day, but the GraphQL API surface is well-documented and the attack complexity is rated Low.
Conditions required:
  • Knowledge of GraphQL subscription schema
  • Duo Chat websocket/subscription endpoint accessible
Where this breaks in practice:
  • No public PoC available yet (day-zero of disclosure)
  • WAF rules inspecting GraphQL payloads may catch anomalous subscription arguments
Detection/coverage: GraphQL query logging; anomalous subscription argument patterns in application logs
STEP 04

Exfiltrate Advanced Search credentials

The deserialized response leaks Advanced Search (Elasticsearch/OpenSearch) instance configurations including connection URLs, authentication credentials, and potentially API keys. The attacker captures these from the GraphQL response. This is the primary documented impact of the vulnerability.
Conditions required:
  • Target instance has Advanced Search configured with Elasticsearch or OpenSearch
Where this breaks in practice:
  • Advanced Search is a Premium/Ultimate feature that requires explicit setup — not all EE instances use it
  • If Elasticsearch uses network-level isolation, stolen creds may not be reachable from the attacker's position
Detection/coverage: Elasticsearch audit logs showing connections from unexpected sources; GitLab application log review
STEP 05

Pivot to Elasticsearch backend

With stolen Elasticsearch credentials, the attacker can directly query the search backend, which indexes all repository content, issues, merge requests, notes, and wiki pages across every project on the instance. This gives broad read access to source code and potentially secrets committed to repositories. If the Elasticsearch instance has write access, data tampering is possible.
Conditions required:
  • Network path from attacker to Elasticsearch endpoint
  • Elasticsearch credentials are valid and not rotated
Where this breaks in practice:
  • Well-architected deployments isolate Elasticsearch behind private subnets unreachable from the internet
  • Credential rotation after detection breaks the chain
Detection/coverage: Elasticsearch access logs; network monitoring for unexpected connections to search cluster ports (9200/9300)
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNot observed. No reports of active exploitation for CVE-2026-87719 as of 2026-09-12. The sibling CVE-2026-85706 (path traversal, CVSS 10.0) is seeing active probes since September 11 per watchTowr, but this deserialization bug has not drawn the same attention.
Proof-of-conceptNone public. No PoC repos identified on GitHub or exploit-db. Reported by kyyblin via HackerOne bug bounty — details likely embargoed per GitLab's responsible disclosure policy.
EPSS scoreNot yet scored — CVE disclosed 2026-09-12 (today). Expect initial EPSS within 24–48 hours.
KEV statusNot listed on CISA KEV catalog as of 2026-09-12.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H — Network-accessible, low complexity, low privilege required, no user interaction, scope changed. The S:C and I:H/A:H components are aggressive given the described impact is credential disclosure rather than RCE.
Affected versionsGitLab EE only: 18.3 ≤ v < 19.1.8, 19.2.0 ≤ v < 19.2.6, 19.3.0 ≤ v < 19.3.2. GitLab CE is not affected.
Fixed versions19.1.8, 19.2.6, 19.3.2 — released September 10, 2026
Exposure dataCyCognito identified >20,000 self-managed GitLab instances reachable on standard web ports via Shodan/Censys. Subset running EE with Duo enabled is significantly smaller.
Disclosure date2026-09-12 (public advisory); patch released 2026-09-10
Reporterkyyblin via HackerOne bug bounty program
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to HIGH (7.5/10)

The single most decisive factor is the Duo Chat access gate: Duo is a paid add-on that requires a separate license on top of GitLab EE Premium/Ultimate, meaning the reachable attack population is a fraction of the already-limited EE self-managed install base. Despite GitLab's role as a CI/CD and source-code platform warranting a HIGH floor, the compounding prerequisites (authentication + Duo entitlement + Advanced Search configured) and the credential-disclosure-not-RCE impact class do not sustain the vendor's CRITICAL 9.9 rating.

HIGH Affected version range and patch availability
MEDIUM Real-world exploitability assessment (no PoC to validate)
LOW Exact blast radius of stolen Elasticsearch credentials across deployment types

Why this verdict

  • Duo Chat gate narrows population significantly. Duo requires a separate paid add-on license (Core/Pro/Enterprise) on top of EE Premium/Ultimate. Many EE deployments have not purchased Duo, and all CE deployments are entirely out of scope. This alone reduces the vulnerable population by an estimated 60–80%.
  • Authentication required. The CVSS PR:L means the attacker needs a valid account. Self-managed instances that disable public registration (enterprise default) require credential theft or insider access — a prior compromise stage that compounds downward pressure.
  • Impact is credential disclosure, not RCE. The documented outcome is theft of Advanced Search (Elasticsearch) configs and credentials. While serious, this is an information-disclosure primitive that requires a second-stage pivot to Elasticsearch to achieve meaningful data access — not arbitrary code execution on the GitLab server itself. The vendor's I:H and A:H are overweighted.
  • Role multiplier: GitLab EE is canonically a CI/CD and source-code management platform — a high-value supply-chain component. If the chain succeeds, stolen Elasticsearch credentials give read access to *all indexed repository content, merge requests, and issues* — potentially including secrets, API keys, and proprietary source code. Blast radius is tenant-to-organization-scale (all projects on the instance). This sets the verdict floor at HIGH and prevents further downgrade despite the friction.
  • No exploitation evidence. No KEV listing, no in-the-wild activity, no public PoC. The sibling CVE-2026-85706 is drawing active probes, but this bug is not — reducing urgency relative to CRITICAL.

Why not higher?

The vendor's CRITICAL (9.9) assumes the deserialization leads to full scope-changed compromise with high integrity and availability impact. In practice, the documented impact is credential disclosure for a specific backend service (Elasticsearch), not arbitrary RCE. The Duo Chat prerequisite dramatically narrows the eligible attacker population — this is not a feature available to every authenticated user, but only to those with a paid add-on entitlement. No PoC or in-the-wild activity exists to demonstrate a broader impact than documented.

Why not lower?

GitLab is a canonical CI/CD and supply-chain platform. Even credential disclosure from a GitLab instance carries outsized risk because the Elasticsearch backend indexes all source code, merge requests, and issues — including secrets that developers inevitably commit. A successful chain ends in organization-scale data exposure. Additionally, ~20,000 self-managed instances are internet-facing, the attack complexity is Low, and deserialization bugs historically evolve from info-disclosure to RCE as researchers probe deeper. The HIGH floor is warranted.

05 · Compensating Control

What to do — in priority order.

  1. Restrict Duo Chat to licensed seats immediately — Enable the duo_chat_requires_licensed_seat (or duo_chat_requires_licensed_seat_sm for self-managed) feature flag to limit Duo Chat to explicitly assigned seats. This shrinks the attack surface to only users with paid Duo seats. Deploy within 30 days per noisgate mitigation SLA for HIGH.
  2. Rotate Advanced Search / Elasticsearch credentials — If you suspect any exposure, rotate Elasticsearch passwords, API keys, and connection strings immediately. Update GitLab's Advanced Search configuration with the new credentials. This breaks any exfiltrated credential chain.
  3. Network-isolate Elasticsearch backends — Ensure Elasticsearch/OpenSearch clusters are in private subnets unreachable from user-facing networks or the internet. Use firewall rules to allow connections only from the GitLab application servers. This prevents pivoting even if credentials are stolen.
  4. Audit GraphQL subscription logs — Review GitLab application logs for unusual GraphQL subscription patterns, particularly targeting Duo Chat endpoints. Set up alerts for anomalous subscription argument lengths or unexpected object references.
  5. Disable public self-registration — If not already done, disable public sign-up on self-managed instances to raise the authentication barrier. This forces attackers to steal or social-engineer credentials before reaching the vulnerability.
What doesn't work
  • IP-based rate limiting on the GitLab web UI — the exploit requires only a single crafted GraphQL request, not brute-force attempts, so rate limiting provides no meaningful protection.
  • GitLab's built-in 2FA/MFA — while 2FA raises the bar for initial authentication, once a valid session exists (including via stolen session tokens or OAuth flows), the deserialization payload works normally within that session.
  • Disabling Advanced Search after exploitation — if credentials were already exfiltrated, disabling the feature in GitLab does not invalidate the stolen Elasticsearch credentials. You must rotate them.
06 · Verification

Crowdsourced verification payload.

Run this script on the GitLab server (or any host with curl and access to the GitLab API) as any user with shell access. Example: bash check_cve_2026_87719.sh https://gitlab.example.com. No special privileges required — it checks the GitLab version via the public API endpoint.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_87719.sh — Detect GitLab EE instances vulnerable to CVE-2026-87719
# Usage: bash check_cve_2026_87719.sh <GITLAB_URL>
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN

set -euo pipefail

if [[ $# -lt 1 ]]; then
  echo "Usage: $0 <GITLAB_URL>"
  echo "Example: $0 https://gitlab.example.com"
  exit 2
fi

GITLAB_URL="${1%/}"

# Fetch version from public API
VERSION_JSON=$(curl -sf "${GITLAB_URL}/api/v4/version" 2>/dev/null || curl -sf "${GITLAB_URL}/api/v4/metadata" 2>/dev/null || true)

if [[ -z "$VERSION_JSON" ]]; then
  echo "UNKNOWN — Could not retrieve GitLab version. API may require authentication."
  echo "Try: curl -s --header 'PRIVATE-TOKEN: <token>' ${GITLAB_URL}/api/v4/version"
  exit 2
fi

VERSION=$(echo "$VERSION_JSON" | grep -oP '"version"\s*:\s*"\K[^"]+' || true)
EDITION=$(echo "$VERSION_JSON" | grep -oP '"edition"\s*:\s*"\K[^"]+' 2>/dev/null || echo "unknown")

if [[ -z "$VERSION" ]]; then
  echo "UNKNOWN — Could not parse version from API response."
  exit 2
fi

echo "Detected GitLab version: $VERSION (edition: $EDITION)"

# CE is not affected
if echo "$EDITION" | grep -qi 'community\|CE'; then
  echo "PATCHED — GitLab Community Edition is not affected by CVE-2026-87719."
  exit 0
fi

# Parse major.minor.patch
IFS='.' read -r MAJOR MINOR PATCH <<< "$(echo "$VERSION" | grep -oP '^[0-9]+\.[0-9]+\.[0-9]+')"

if [[ -z "$MAJOR" || -z "$MINOR" || -z "$PATCH" ]]; then
  echo "UNKNOWN — Could not parse version components from: $VERSION"
  exit 2
fi

# Affected: EE 18.3 <= v < 19.1.8, 19.2.0 <= v < 19.2.6, 19.3.0 <= v < 19.3.2
# Not affected: < 18.3, >= 19.1.8 (on 19.1.x), >= 19.2.6 (on 19.2.x), >= 19.3.2 (on 19.3.x)

VULNERABLE=false

if (( MAJOR < 18 )); then
  VULNERABLE=false
elif (( MAJOR == 18 && MINOR < 3 )); then
  VULNERABLE=false
elif (( MAJOR == 18 && MINOR >= 3 )); then
  VULNERABLE=true
elif (( MAJOR == 19 && MINOR == 0 )); then
  VULNERABLE=true
elif (( MAJOR == 19 && MINOR == 1 )); then
  if (( PATCH < 8 )); then
    VULNERABLE=true
  fi
elif (( MAJOR == 19 && MINOR == 2 )); then
  if (( PATCH < 6 )); then
    VULNERABLE=true
  fi
elif (( MAJOR == 19 && MINOR == 3 )); then
  if (( PATCH < 2 )); then
    VULNERABLE=true
  fi
fi

if $VULNERABLE; then
  echo "VULNERABLE — GitLab $VERSION is affected by CVE-2026-87719."
  echo "Update to 19.1.8, 19.2.6, or 19.3.2 immediately."
  exit 1
else
  echo "PATCHED — GitLab $VERSION is not in the affected range for CVE-2026-87719."
  exit 0
fi
07 · Bottom Line

If you remember one thing.

TL;DR
Patch your GitLab EE instances to 19.1.8, 19.2.6, or 19.3.2 this week. While noisgate downgrades this from CRITICAL to HIGH — meaning the noisgate mitigation SLA gives you 30 days to deploy compensating controls and the noisgate remediation SLA allows up to 180 days for the full patch — the fact that this dropped alongside CVE-2026-85706 (CVSS 10.0, already seeing active probes) means you should be patching this release *anyway* and both fixes come in the same update. Monday morning: (1) confirm whether your EE instances have Duo Chat enabled and Advanced Search configured — if neither, your exposure is zero; (2) if both are active, enable the duo_chat_requires_licensed_seat feature flag immediately to restrict the attack surface; (3) rotate your Elasticsearch/OpenSearch credentials as a precaution; (4) schedule the patch deployment for this sprint. Do not wait for the 30-day window if your GitLab instance is internet-facing.

Sources

  1. GitLab Critical Patch Release 19.3.2, 19.2.6, 19.1.8
  2. CybersecurityNews — GitLab Patches Critical Flaws
  3. The Hacker News — GitLab CVSS 10 File-Read Flaw Draws In-the-Wild Probes
  4. BleepingComputer — GitLab urges users to patch max severity path traversal flaw
  5. SecurityWeek — GitLab Vulnerability Exploited One Day After Disclosure
  6. GitLab Docs — Duo Chat
  7. GitLab Docs — Elasticsearch / Advanced Search
  8. GitLab Forum — Critical Patch Release Announcement
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.