GitLab has released patches for CVE-2026-90970, a critical vulnerability in the GitLab AI Gateway carrying a CVSS score of 9.9 (Critical). The flaw allows an authenticated user with access to the Duo Agent Platform to escape the prompt sandbox and execute arbitrary commands on self-hosted AI Gateway instances. If you run GitLab self-managed with the AI Gateway deployed — particularly if Duo Agent Platform features are enabled — this is a patch-now event, not a patch-later event.
What makes this bug stand out isn't just the score. It sits at the intersection of two of the highest-risk trends we're tracking in 2026: AI/LLM-integrated development tooling becoming a privileged execution surface, and sandbox-escape primitives that convert low-privilege authenticated access into host-level command execution. In our IR work this year, CI/CD infrastructure remains one of the most consequential targets an attacker can land on — a compromised GitLab host means source code, secrets in CI variables, and a launch point into build and deployment pipelines. A 9.9 RCE-adjacent flaw on that infrastructure, exploitable by any authenticated Duo user, demands immediate triage.
This post breaks down what's known about the flaw, how to hunt for abuse, and how to remediate and harden self-hosted AI Gateway deployments.
Technical Analysis
Affected Components
- Product: GitLab AI Gateway (the service that brokers communication between GitLab and AI/LLM providers, enabling GitLab Duo features)
- Affected deployments: Self-hosted / self-managed AI Gateway instances. GitLab.com and GitLab-managed AI infrastructure are patched by GitLab directly — the exposure here falls on organizations running their own gateway.
- Exploitation prerequisite: An authenticated user with access to the Duo Agent Platform. This is not an unauthenticated remote flaw — but "authenticated" in a large GitLab deployment can mean hundreds of developers, contractors, or a single phished credential.
How the Vulnerability Works
At a high level, CVE-2026-90970 is a prompt sandbox escape. The Duo Agent Platform executes AI-driven agentic workflows inside a sandboxed environment intended to constrain what generated prompts and agent actions can do on the underlying host. The vulnerability allows a crafted interaction with the platform — originating from a legitimate authenticated session — to break out of that sandbox boundary and reach command execution on the gateway host itself.
From a defender's perspective, the attack chain looks like this:
- Attacker holds (or obtains) valid GitLab credentials with Duo Agent Platform entitlements.
- Attacker interacts with the Duo Agent Platform in a way that escapes the prompt sandbox — effectively weaponizing the agent's execution context.
- Arbitrary commands execute on the self-hosted AI Gateway instance, typically under the service account running the gateway workload.
- From the gateway, the attacker can pivot: the AI Gateway holds API credentials, model provider keys, and network adjacency to the GitLab Rails application, internal registries, and CI infrastructure.
The 9.9 CVSS score reflects the combination of low attack complexity post-authentication, scope change (sandbox escape crossing a security boundary), and full confidentiality/integrity/availability impact on the gateway host.
Why Self-Hosted AI Gateways Are a High-Value Target
The AI Gateway is not a peripheral service. It:
- Holds credentials for upstream LLM providers (Anthropic, OpenAI, Vertex, self-hosted models).
- Sits in the trust path between GitLab and AI services, with network reachability into internal segments that are often flat.
- Is frequently deployed as a container or VM that teams treat as "just middleware" — outside the patch cadence and EDR coverage applied to the GitLab instance itself.
That last point is where we've seen organizations get burned: AI-adjacent infrastructure deployed during a Duo pilot, forgotten by the CMDB, and absent from vulnerability scans. Confirm whether your environment actually runs a self-hosted gateway before assuming you're unaffected.
Exploitation Status
As of this writing, the vulnerability has been disclosed and patched by GitLab, with the fix announced alongside the CVE. We assess the following:
- Public exploit/PoC: No confirmed public exploit code at time of writing, though the 9.9 score and clear exploitation primitive (sandbox escape → command execution) make this an attractive reverse-engineering target. Expect PoC development attempts within days of patch diffing.
- Active in-the-wild exploitation: Not publicly confirmed at disclosure time. Treat this as a shrinking window, not a safe one.
- CISA KEV: Not yet listed as of publication — monitor the KEV catalog and GitLab's advisories closely.
Historically, critical GitLab vulnerabilities move from disclosure to mass scanning within 48–72 hours. Assume internet-exposed GitLab instances with reachable AI Gateway endpoints will be enumerated.
Detection & Response
The most reliable detection surface for post-exploitation is unexpected command execution spawned by the AI Gateway process or its container runtime. A healthy AI Gateway does not spawn interactive shells, download tools, or initiate unusual outbound connections. The detections below target that behavioral delta.
Sigma Rules
---
title: GitLab AI Gateway Spawning Shell or Command Interpreter
tid: 9b2c4f71-3e8a-4d56-a91f-7c2e5d8b1a34
status: experimental
description: Detects shell or interpreter processes spawned by the GitLab AI Gateway process or its container runtime, consistent with sandbox escape and command execution via CVE-2026-90970.
references:
- https://securityaffairs.com/200283/hacking/cve-2026-90970-critical-gitlab-ai-gateway-flaw-fixed.html
- https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.execution
- attack.t1059
- attack.t1202
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|contains:
- 'ai-gateway'
- 'gitlab'
- 'dockerd'
- 'containerd'
- 'python'
selection_child:
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
- '/zsh'
- '/python'
- '/python3'
- '/perl'
- '/curl'
- '/wget'
- '/nc'
- '/ncat'
- '/socat'
filter_healthcheck:
CommandLine|contains:
- 'healthcheck'
- 'readiness'
- 'liveness'
condition: selection_parent and selection_child and not filter_healthcheck
falsepositives:
- Container health checks and liveness probes
- Legitimate AI Gateway plugin or model-runner invocation (tune by baselining normal gateway child processes)
level: high
---
title: Suspicious Outbound Connection from GitLab AI Gateway Workload
tid: 4d7e1a92-6c5b-48f3-b2d8-9a1c6e4f7035
status: experimental
description: Detects network connections from the AI Gateway process to destinations other than expected LLM provider endpoints and the GitLab instance, potentially indicating post-exploitation C2 or data exfiltration following CVE-2026-90970 abuse.
references:
- https://securityaffairs.com/200283/hacking/cve-2026-90970-critical-gitlab-ai-gateway-flaw-fixed.html
- https://attack.mitre.org/techniques/T1071/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.command_and_control
- attack.t1071
- attack.exfiltration
- attack.t1041
logsource:
category: network_connection
product: linux
detection:
selection:
Image|contains:
- 'ai-gateway'
- 'python'
filter_expected:
DestinationHostname|contains:
- 'api.openai.com'
- 'api.anthropic.com'
- 'googleapis.com'
- 'gitlab.com'
- 'cloud.gitlab.com'
condition: selection and not filter_expected
falsepositives:
- Self-hosted or proxy LLM endpoints (add your internal model endpoints to the filter)
- Telemetry and package repositories during updates
level: medium
A note on tuning: the first rule will fire in environments where the AI Gateway legitimately invokes model runners or plugin subprocesses. Baseline your gateway's normal child-process tree for a week before raising the alert severity. The second rule is only as good as your allowlist of legitimate LLM endpoints — build that allowlist from your actual Duo configuration, not from our examples.
KQL (Microsoft Sentinel / Defender)
The following query hunts Linux Syslog and CEF-ingested process events from AI Gateway hosts in Sentinel. It assumes Syslog or auditd process execution data is forwarded from the gateway VM or Kubernetes node.
// Hunt for command execution spawned by GitLab AI Gateway processes (CVE-2026-90970 post-exploitation behavior)
let SuspiciousChildren = dynamic(["/bin/sh", "/bin/bash", "/bin/dash", "/usr/bin/python", "/usr/bin/python3", "/usr/bin/curl", "/usr/bin/wget", "/usr/bin/nc", "/usr/bin/perl", "/usr/bin/socat"]);
let Lookback = 14d;
Syslog
| where TimeGenerated >= ago(Lookback)
| where ProcessName has_any ("sh", "bash", "python", "curl", "wget", "nc", "perl", "socat")
| where SyslogMessage has_any ("ai-gateway", "ai_gateway", "duo", "gitlab")
or Computer has "gateway"
| extend ChildProcess = ProcessName,
CommandLine = SyslogMessage
| where CommandLine has_any ("bash -i", "sh -i", "-c ", "base64", "/dev/tcp/", "curl http", "wget http", "chmod +x")
| project TimeGenerated, Computer, ChildProcess, CommandLine, HostIP, SeverityLevel
| order by TimeGenerated desc
;
// Correlate with unusual outbound connections from gateway hosts
CommonSecurityLog
| where TimeGenerated >= ago(Lookback)
| where DeviceVendor == "GitLab" or SourceHostName has "gateway"
| where DestinationPort !in (443, 80) or DestinationAddress !startswith "10."
| summarize ConnectionCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)
by SourceHostName, DestinationAddress, DestinationPort
| where ConnectionCount < 50 // rare destinations are more interesting than high-volume expected ones
| order by LastSeen desc
If your AI Gateway runs in Kubernetes, also hunt Defender for Containers / kube-audit data for exec into gateway pods — kubectl exec activity against the gateway namespace outside of known admin sessions is a strong post-compromise signal.
Velociraptor VQL
Use this artifact to hunt across your gateway fleet (or any Linux endpoints enrolled in Velociraptor) for processes with suspicious parentage and recently written files in gateway working directories — useful for identifying dropped tools or webshell-style artifacts after sandbox escape.
-- Hunt for suspicious child processes and recently modified files related to GitLab AI Gateway (CVE-2026-90970)
SELECT Pid, Ppid, Name, Exe, CommandLine, Username, CreateTime
FROM pslist()
WHERE (
CommandLine =~ '(?i)(bash -i|sh -i|/dev/tcp/|base64 -d|curl http|wget http|nc -|socat)'
OR Name =~ '(?i)^(sh|bash|dash|nc|ncat|socat)$'
)
AND NOT CommandLine =~ '(?i)(healthcheck|liveness|readiness)'
-- Identify recently modified files in common AI Gateway deployment and temp paths
SELECT FullPath, Size, Mtime, Atime, Ctime
FROM glob(globs=['/srv/gitlab-ai-gateway/**', '/opt/gitlab/**/ai-gateway/**', '/tmp/**', '/var/tmp/**', '/dev/shm/**'])
WHERE Mtime > now() - 1209600
AND NOT IsDir
AND (FullPath =~ '(?i)\.(py|sh|elf|so)$' OR FullPath =~ '(?i)/(tmp|shm)/')
ORDER BY Mtime DESC
Note: adjust the glob paths to your actual gateway installation layout — containerized deployments should be hunted at the node level or via container runtime mounts.
Remediation / Verification Script
Run this on self-hosted AI Gateway hosts to confirm the gateway is present, check its version against the patched release, and apply compensating network controls pending patch.
#!/usr/bin/env bash
# CVE-2026-90970 - GitLab AI Gateway verification and hardening helper
# Run with sudo on the AI Gateway host.
set -euo pipefail
echo "=== [1] Locate AI Gateway installation ==="
if command -v docker >/dev/null 2>&1; then
echo "[+] Checking for AI Gateway containers..."
docker ps --format '{{.Names}} {{.Image}} {{.Status}}' | grep -i 'ai-gateway\|ai_gateway' || echo "[-] No running AI Gateway containers found."
echo "[+] Image digests (compare against GitLab advisory patched images):"
docker images --digests | grep -i 'ai-gateway' || true
fi
echo ""
echo "=== [2] Check gateway version ==="
# Adjust path to your deployment; the version endpoint/file varies by install method
if command -v docker >/dev/null 2>&1 && docker ps --format '{{.Names}}' | grep -qi 'ai-gateway'; then
GW_CONTAINER=$(docker ps --format '{{.Names}}' | grep -i 'ai-gateway' | head -1)
docker exec "$GW_CONTAINER" sh -c 'cat /app/VERSION 2>/dev/null || pip show gitlab-ai-gateway 2>/dev/null || echo "version check manual"' || true
else
pip show gitlab-ai-gateway 2>/dev/null || echo "[-] Non-container install not found via pip; check your deployment method manually."
fi
echo ""
echo "=== [3] Compensating control: restrict egress from gateway host (pending patch) ==="
echo " Allow ONLY: GitLab instance, approved LLM provider endpoints, DNS/NTP."
echo " Example nftables egress restriction (review before applying):"
cat <<'EOF'
# table inet gw_egress {
# chain output {
# type filter hook output priority 0; policy drop;
# oif lo accept
# ip daddr <GITLAB_INSTANCE_IP> tcp dport 443 accept
# ip daddr <LLM_PROVIDER_IPS> tcp dport 443 accept
# udp dport {53, 123} accept
# }
# }
EOF
echo ""
echo "=== [4] Audit recent gateway child processes (last 24h, if auditd present) ==="
if command -v ausearch >/dev/null 2>&1; then
ausearch -ts recent -k exec 2>/dev/null | grep -iE 'ai-gateway|bash -i|sh -i|/dev/tcp|curl http|wget http' | tail -50 || echo "[-] No matching audit records (or no exec key configured)."
else
echo "[-] auditd not installed. Consider enabling execve auditing on this host."
fi
echo ""
echo "=== [5] Duo Agent Platform entitlement review reminder ==="
echo " In GitLab Admin > Duo settings: enumerate users/groups with Duo Agent Platform access."
echo " Remove entitlements not tied to an active business need."
echo ""
echo "[DONE] Cross-reference the gateway version above against the patched versions"
echo " in GitLab's official advisory and upgrade immediately if vulnerable."
Remediation
- Upgrade the AI Gateway immediately. Apply the patched AI Gateway release referenced in GitLab's security advisory for CVE-2026-90970. Confirm the exact fixed version from GitLab's official release notes and advisory before declaring remediation complete — do not rely on package-manager "latest" tags without verifying the digest. Reference: Security Affairs coverage and GitLab's official security release notes at
about.gitlab.com/releases/categories/releases/and the GitLab security advisories page. - Inventory first. Many organizations don't know they run a self-hosted gateway. Check your GitLab Admin Area (Admin > Settings > AI-powered features / Duo) to determine whether your instance points at GitLab-hosted AI infrastructure or a self-managed gateway URL. Scan for gateway containers and VMs across your environment.
- Reduce the blast radius while patching. Since exploitation requires an authenticated Duo Agent Platform user, audit and temporarily restrict Duo Agent Platform entitlements to the minimum necessary population. Enforce phishing-resistant MFA on all GitLab accounts — a phished developer credential plus this CVE is a full RCE chain.
- Segment the gateway. The AI Gateway should sit in a restricted segment with egress limited to the GitLab instance and approved LLM provider endpoints only, and no inbound access except from GitLab. There is rarely a legitimate reason for a gateway to reach general internet destinations or internal management subnets.
- Instrument and baseline. Ensure the gateway host is covered by EDR and process auditing (auditd execve rules, Sysmon-for-Linux, or your EDR's Linux sensor). Baseline normal gateway child processes so the Sigma rules above fire on genuine anomalies.
- Hunt retroactively. Once patched, run the KQL and VQL hunts above across at least the last 14 days of telemetry. If you find evidence of sandbox escape behavior, treat it as an incident: the gateway's LLM provider keys, GitLab tokens, and any reachable CI secrets must be rotated.
- Watch for follow-on exploitation. Monitor the CISA KEV catalog and GitLab's advisories over the coming weeks. If exploitation is confirmed in the wild, expect a federal remediation deadline to follow for KEV listing.
Bottom Line
CVE-2026-90970 is a textbook example of AI platform risk materializing in production: an agentic AI feature with a sandbox boundary that didn't hold, on infrastructure that organizations systematically under-instrument. Patch the gateway, audit who has Duo Agent Platform access, and treat your AI Gateway with the same defensive rigor you apply to GitLab itself — because post-exploitation, it's the same thing.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.