Back to Intelligence

CISA KEV Alert: Maximum-Severity GitLab Flaw Under Active Exploitation — Detection and Remediation Guide

SA
Security Arsenal Team
September 14, 2026
9 min read

CISA has issued a public warning that threat actors are actively exploiting a maximum-severity vulnerability in GitLab in real-world attacks. When CISA moves a flaw to its Known Exploited Vulnerabilities (KEV) catalog — and publicly calls out live exploitation — the window between disclosure and compromise has already closed. If your organization operates a self-hosted GitLab Community Edition (CE) or Enterprise Edition (EE) instance, you should treat this as an incident-response scenario, not a routine patch cycle.

GitLab sits at the center of the software supply chain. It holds source code, CI/CD pipeline secrets, deployment credentials, API tokens, and often has network-level trust into build runners, artifact registries, and production deployment targets. A maximum-severity flaw in GitLab isn't just a web server compromise — it's a potential supply-chain foothold that lets an attacker poison builds, harvest credentials, and pivot into every system your pipelines touch. That is precisely why this class of target attracts both financially motivated actors and nation-state operators.

Technical Analysis

What's affected

Self-hosted GitLab CE and EE instances running vulnerable release branches are the primary exposure. GitLab.com (the SaaS offering) is patched by GitLab directly, but your self-managed instances — including instances deployed in private cloud, on-prem data centers, and 'temporary' dev environments that quietly became production — are your responsibility. In every engagement where we've responded to CI/CD compromise, at least one forgotten or shadow instance was the entry point.

Maximum-severity (CVSS 9.x–10.0) flaws in GitLab historically cluster around a handful of high-impact classes: authentication bypass and account takeover, path traversal and arbitrary file read/write, insecure direct object references escalating to project takeover, and remote code execution through pipeline or import/export functionality. Any of these on an internet-reachable instance means an unauthenticated or low-privilege attacker can gain control of the application — and typically the underlying host via the git or gitlab service account context.

Why exploitation escalates fast

Once an attacker lands on a GitLab host, the post-exploitation playbook is well established and we see it consistently in IR casework:

  1. Credential harvesting — extracting CI/CD variables, runner registration tokens, personal access tokens, and SSH keys from the GitLab database and configuration.
  2. Webshell or persistence implantation — dropping scripts into GitLab's public upload directories or modifying application files under /var/opt/gitlab and /opt/gitlab.
  3. Pipeline poisoning — injecting malicious steps into .gitlab-ci.yml files so every subsequent build executes attacker code with runner-level privileges.
  4. Lateral movement — using harvested tokens to access container registries, cloud environments, and deployment targets.

Exploitation status

Per the CISA warning, this vulnerability is confirmed exploited in the wild and has been added to the CISA KEV catalog. KEV listing triggers a binding remediation deadline for U.S. federal civilian agencies, but every private-sector defender should treat KEV deadlines as their own — the actors exploiting KEV-listed flaws do not discriminate by sector. Check the CISA KEV catalog for the specific due date, and pull the exact fixed version numbers from GitLab's security release advisories.

Detection & Response

Patching closes the door going forward — it does nothing for an attacker who got in last week. Hunt for post-exploitation behavior on every GitLab host, especially internet-facing ones, before and after you patch. The detections below focus on the highest-fidelity behavioral signals we use when hunting GitLab compromise: the GitLab service processes spawning shells, webshell artifacts in GitLab data paths, and anomalous outbound connections from the server.

Sigma Rules

YAML
---
title: GitLab Service Process Spawning Shell or Command Interpreter
id: 3f8a2c91-7d4e-4b1a-9c6f-2e5d8a1b4f09
status: experimental
description: Detects GitLab application components (workhorse, puma, gitaly, sidekiq) spawning shell interpreters or scripting engines, a strong indicator of webshell or post-RCE command execution on a GitLab host.
references:
  - https://www.cisa.gov/known-exploited-vulnerabilities-catalog
  - https://about.gitlab.com/security-releases/
  - https://attack.mitre.org/techniques/T1190/
author: Security Arsenal
date: 2026/02/10
tags:
  - attack.initial_access
  - attack.t1190
  - attack.execution
  - attack.t1059
logsource:
  category: process_creation
  product: linux
detection:
  selection_parent:
    ParentImage|endswith:
      - '/gitlab-workhorse'
      - '/puma'
      - '/gitaly'
      - '/sidekiq'
      - '/gitlab-rails'
  selection_child:
    Image|endswith:
      - '/sh'
      - '/bash'
      - '/dash'
      - '/zsh'
      - '/python'
      - '/python3'
      - '/perl'
      - '/ruby'
      - '/curl'
      - '/wget'
      - '/nc'
      - '/ncat'
  condition: selection_parent and selection_child
falsepositives:
  - GitLab backup or maintenance scripts invoked through application hooks (rare; baseline per host)
level: high
---
title: Webshell or Script Dropped in GitLab Data and Upload Directories
id: 8c1e5b74-3a2f-4d98-b7e1-6f4c9a2d5e08
status: experimental
description: Detects creation of executable script files in GitLab public upload, artifacts, or tmp directories, consistent with webshell deployment following exploitation of a GitLab web vulnerability.
references:
  - https://www.cisa.gov/known-exploited-vulnerabilities-catalog
  - https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/02/10
tags:
  - attack.persistence
  - attack.t1505.003
logsource:
  category: file_event
  product: linux
detection:
  selection_path:
    TargetFilename|contains:
      - '/var/opt/gitlab/gitlab-rails/uploads/'
      - '/var/opt/gitlab/gitlab-rails/shared/artifacts/'
      - '/var/opt/gitlab/gitlab-rails/tmp/'
      - '/opt/gitlab/embedded/service/gitlab-rails/public/'
  selection_ext:
    TargetFilename|endswith:
      - '.php'
      - '.jsp'
      - '.jspx'
      - '.py'
      - '.rb'
      - '.sh'
      - '.pl'
  condition: selection_path and selection_ext
falsepositives:
  - Legitimate CI artifacts containing scripts (tune to uploads/ and tmp/ paths if noisy)
level: high
---
title: Outbound Connection from GitLab Host to Rare External Destination
id: 5d2f9a18-4c6b-4e1f-8a3d-9b7c2e4f6a01
status: experimental
description: Detects the git or gitlab service account establishing outbound network connections to non-standard destinations, consistent with C2 or data exfiltration from a compromised GitLab server.
references:
  - https://attack.mitre.org/techniques/T1071/
  - https://attack.mitre.org/techniques/T1105/
author: Security Arsenal
date: 2026/02/10
tags:
  - attack.command_and_control
  - attack.t1071
  - attack.exfiltration
logsource:
  category: network_connection
  product: linux
detection:
  selection:
    User:
      - 'git'
      - 'gitlab'
      - 'gitlab-www'
      - 'gitlab-redis'
    Initiated: 'true'
  filter_legit:
    DestinationIp|contains:
      - '10.'
      - '172.16.'
      - '192.168.'
  condition: selection and not filter_legit
falsepositives:
  - GitLab checking for updates or reaching configured package mirrors (allowlist known-good destinations per environment)
level: medium

KQL — Microsoft Sentinel / Defender

The following hunt queries GitLab syslog and process telemetry ingested into Sentinel. Run it across the last 30 days against every host tagged as a GitLab server. It looks for GitLab application processes spawning interpreters or download tooling — the single highest-fidelity signal of post-exploitation activity on these hosts.

KQL — Microsoft Sentinel / Defender
// Hunt: GitLab service processes spawning shells, interpreters, or downloaders
// Scope: hosts ingesting Linux syslog/auditd process events into Sentinel
let lookback = 30d;
let gitlab_parents = dynamic(["gitlab-workhorse", "puma", "gitaly", "sidekiq", "gitlab-rails"]);
let suspicious_children = dynamic(["sh", "bash", "dash", "zsh", "python", "python3", "perl", "curl", "wget", "nc", "ncat", "socat"]);
union isfuzzy=true
  (Syslog
   | where TimeGenerated > ago(lookback)
   | where ProcessName in~ (suspicious_children)
   | where SyslogMessage has_any (gitlab_parents)
   | project TimeGenerated, Computer, ProcessName, SyslogMessage, HostIP),
  (DeviceProcessEvents
   | where TimeGenerated > ago(lookback)
   | where InitiatingProcessFileName has_any (gitlab_parents)
   | where FileName in~ (suspicious_children)
   | project TimeGenerated, DeviceName, FileName, ProcessCommandLine, InitiatingProcessFileName, AccountName)
| order by TimeGenerated desc;

// Hunt: GitLab hosts making outbound connections to rare destinations
// Requires CEF/firewall or Defender network telemetry
let gitlab_hosts = (Syslog
   | where TimeGenerated > ago(7d)
   | where SyslogMessage has "gitlab"
   | summarize by Computer);
CommonSecurityLog
| where TimeGenerated > ago(lookback)
| where DeviceAction !in ("deny", "drop")
| where SourceHostName in (gitlab_hosts) or SourceIP in (gitlab_hosts)
| where DestinationIP !startswith "10." and DestinationIP !startswith "192.168." and DestinationIP !startswith "172.16."
| summarize ConnectionCount=count(), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort
| where ConnectionCount < 50
| order by FirstSeen asc;

Velociraptor VQL

This artifact hunts a live GitLab host for the forensic residue of exploitation: suspicious child processes of GitLab services and recently written script files in GitLab data paths.

VQL — Velociraptor
-- Hunt GitLab hosts for post-exploitation: suspicious child processes and dropped scripts
SELECT Pid, Ppid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE (Name =~ '(?i)^(sh|bash|dash|python|python3|perl|curl|wget|nc|ncat|socat)$')
  AND (Username =~ '(?i)git|gitlab')

SELECT FullPath, Size, Mtime, Ctime
FROM glob(globs=[
  '/var/opt/gitlab/gitlab-rails/uploads/**/*.sh',
  '/var/opt/gitlab/gitlab-rails/uploads/**/*.php',
  '/var/opt/gitlab/gitlab-rails/uploads/**/*.py',
  '/var/opt/gitlab/gitlab-rails/tmp/**/*.sh',
  '/var/opt/gitlab/gitlab-rails/tmp/**/*.rb',
  '/opt/gitlab/embedded/service/gitlab-rails/public/**/*.php'
])
WHERE Mtime > now() - 2592000
ORDER BY Mtime DESC

Verification and Hardening Script

Run this on each GitLab host to confirm the installed version, identify exposure, and check for the most common persistence artifacts. Compare the reported version against the fixed versions in GitLab's security advisory — if you're behind, patch immediately.

Bash / Shell
#!/bin/bash
# GitLab security posture check — run as root on each self-hosted GitLab host

echo "=== Installed GitLab version ==="
gitlab-rake gitlab:env:info 2>/dev/null || cat /opt/gitlab/version-manifest.txt | head -5

echo ""
echo "=== Is this host internet-reachable? (listening ports) ==="
ss -tlnp | grep -E ':(80|443|22)\s' 

echo ""
echo "=== Suspicious child processes of GitLab services ==="
ps -eo pid,ppid,user,comm,args --forest | grep -E 'gitlab-workhorse|puma|gitaly|sidekiq' -A1 | grep -E 'bash|sh$|python|perl|curl|wget|nc ' || echo "None found"

echo ""
echo "=== Recently modified files in GitLab data paths (last 14 days) ==="
find /var/opt/gitlab/gitlab-rails/uploads /var/opt/gitlab/gitlab-rails/tmp \
  -type f \( -name '*.sh' -o -name '*.php' -o -name '*.py' -o -name '*.rb' \) \
  -mtime -14 -ls 2>/dev/null || echo "None found"

echo ""
echo "=== Local admin users created in GitLab (review for unknown accounts) ==="
gitlab-rails runner 'User.admins.each { |u| puts "#{u.username} | #{u.email} | created: #{u.created_at} | last_sign_in: #{u.last_sign_in_at}" }' 2>/dev/null

echo ""
echo "=== Active personal access tokens (rotate anything unrecognized) ==="
gitlab-rails runner 'PersonalAccessToken.active.each { |t| puts "#{t.user&.username} | #{t.name} | expires: #{t.expires_at}" }' 2>/dev/null

echo ""
echo "Review complete. Cross-reference findings with your GitLab access logs at /var/log/gitlab/gitlab-rails/"

Remediation

  1. Patch immediately. Upgrade all self-hosted GitLab CE/EE instances to the fixed release specified in GitLab's security release advisories. GitLab publishes exact fixed version numbers per release branch in each advisory — verify your installed version against those, not against 'we patched recently.' Meet the CISA KEV remediation deadline; treat it as your own even if you are not a federal agency.

  2. Assume compromise on internet-facing instances. If a vulnerable instance was reachable from the internet before patching, patch-and-move-on is not sufficient. Run the hunts above, review GitLab authentication and audit logs (/var/log/gitlab/gitlab-rails/audit_json.log, production_json.log) for anomalous logins, project exports, and admin actions, and escalate to full IR if anything is unexplained.

  3. Rotate credentials at supply-chain scope. Any instance confirmed or suspected compromised requires rotation of: CI/CD variables, runner registration and authentication tokens, personal access tokens, deploy keys and tokens, SSH keys stored in GitLab, and any cloud or registry credentials referenced in pipelines. This is painful and non-negotiable — tokens harvested from GitLab are routinely used weeks after the initial intrusion.

  4. Reduce exposure permanently. GitLab should not be internet-facing unless the business case demands it. Place it behind VPN or zero-trust access, enforce SSO with MFA, restrict sign-ups, and segment the host from deployment targets. Enable GitLab's audit event streaming to your SIEM so the detections above have reliable telemetry.

  5. Inventory your shadow instances. Query your asset inventory, certificate transparency logs, and external attack surface monitoring for gitlab subdomains and instances on non-standard ports. The forgotten staging instance is the one that gets popped.

Related Resources

Security Arsenal Red Team Services AlertMonitor Platform Book a SOC Assessment pen-testing Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.