Patch GitLab CVE-2026-110264: inventory, fixed versions, migrations, and detection
Patch self-managed GitLab against CVE-2026-110264: inventory every instance, check the served version per install type, upgrade to the fixed release for your minor line (handling the DB migrations on 19.4.3 and 19.3.6), and run GitLab's detection rules to check for exploitation.
This runbook covers self-managed GitLab only. GitLab.com and GitLab Dedicated are already fixed. For help planning an upgrade off an unsupported version, see Cloud Migration, or book a consulting session.
Symptoms
There is no error to wait for. The flaw is silent: a successful attempt does not reliably crash the server. You are affected by version, not by a log line.
- Any self-managed GitLab CE/EE instance on a version from 7.0 up to the 21 October patch is vulnerable.
- Instances patched on 12 October (19.4.2, 19.3.5, 19.2.8) are still vulnerable to this CVE. That patch fixed a different flaw (CVE-2026-97229).
- GitLab.com and GitLab Dedicated (on fixed internal builds) are not affected.
Step 1: inventory every instance
List every GitLab server you run, including the ones easy to forget:
- Geo secondaries (read-only replicas)
- Staging, QA, and demo instances
- Disaster-recovery standbys
- Old or “temporary” instances nobody owns anymore
A forgotten instance on a vulnerable version is a full unauthenticated RCE entry point. Treat the inventory as the actual deliverable of this step.
Step 2: check the version each instance serves
Check what the application actually runs, per install type:
# Linux package (Omnibus)
sudo cat /opt/gitlab/embedded/service/gitlab-rails/VERSION
# Docker
docker exec <container> cat /opt/gitlab/embedded/service/gitlab-rails/VERSION
# Helm chart: read the APP VERSION column, not the chart version
helm list --all-namespaces | grep -i gitlab
# API (any install type) - needs a token
curl --header "PRIVATE-TOKEN: <your-token>" \
"https://gitlab.example.com/api/v4/version"
Signed-in users can also read the version at /help in the browser. For the Helm chart, if you set global.gitlabVersion, that value wins over the chart’s app version.
Step 3: pick the fixed version for your line
Compare the running version to the table and upgrade within your current minor line. A patch-level upgrade (for example 19.4.1 to 19.4.3) needs no extra upgrade stops.
| If you run | Upgrade to | Notes |
|---|---|---|
| 19.5 | 19.5.1 | All 12 fixes |
| 19.4 | 19.4.3 | All 12 fixes, includes DB migrations |
| 19.3 | 19.3.6 | All 12 fixes, includes DB migrations |
| 19.2 | 19.2.9 | Critical fix only |
| 19.1 | 19.1.9 | Critical fix only |
| 19.0 | 19.0.10 | Critical fix only |
| 18.11 | 18.11.13 | Critical fix only |
| 18.10 and older | No fixed release | Upgrade to a supported line (see Step 6) |
The 19.2, 19.1, 19.0, and 18.11 releases are backports carrying the critical fix only. The other 11 fixes from this patch day (two rated high) are in 19.3.6, 19.4.3, and 19.5.1 only. If you are on 19.2 or older and want the full set, plan a move to 19.3.6 or later, which may need upgrade stops.
Step 4: apply the patch (mind the migrations)
Only 19.4.3 and 19.3.6 include database migrations. On a single-node server, GitLab stays down until the migrations finish, so schedule a short window. Multi-node installs can follow GitLab’s zero-downtime upgrade procedure.
# Linux package (Omnibus) - Debian/Ubuntu
sudo apt update && sudo apt install gitlab-ce=19.4.3-ce.0 # or gitlab-ee=19.4.3-ee.0
# Linux package - RHEL/Amazon Linux
sudo dnf install gitlab-ce-19.4.3-ce.0
# Docker: pull the exact tag and recreate
docker pull gitlab/gitlab-ce:19.4.3-ce.0
# then recreate the container with the same volumes/config
# Helm: set the image tag to the fixed version and upgrade
helm upgrade gitlab gitlab/gitlab --reuse-values \
--set global.gitlabVersion=19.4.3
# After the package install, reconfigure (Omnibus)
sudo gitlab-ctl reconfigure
Pin the exact fixed version rather than “latest” so every node in the fleet lands on the same build.
Step 5: verify the patch
# 1. Confirm the served version matches the fixed release
sudo cat /opt/gitlab/embedded/service/gitlab-rails/VERSION
# Expected: 19.4.3 (or whichever fixed version you targeted)
# 2. Confirm migrations finished and the app is healthy (Omnibus)
sudo gitlab-ctl status
sudo gitlab-rake db:migrate:status 2>/dev/null | tail -5
# Expected: all services "run", no pending migrations
# 3. Confirm the instance answers over HTTP
curl -s -o /dev/null -w "%{http_code}\n" https://gitlab.example.com/-/health
# Expected: 200
Repeat Steps 2 through 5 for every instance from your inventory, including Geo secondaries and staging.
Step 6: if you are on 18.10 or older
There is no fixed release below the 18.11 line, so you cannot patch in place. Upgrade to a supported version. GitLab upgrades across several minor versions require staged upgrade stops (specific intermediate versions you must pass through), so this is a planned migration, not a one-shot apt upgrade. Until it is done, reduce exposure: take the instance off the public internet, or at minimum reduce public project visibility, since the unauthenticated path needs a public project holding a crafted .org file. That narrows the attack; it does not close it.
Step 7: check for exploitation attempts
GitLab published two detection rules (Sigma format, in its open-source TLDR framework) that run over application logs:
- Org-mode render error burst: one client causing five or more Org-mode render timeouts within 30 minutes (
exceptions_json.log). - Onigmo native worker crash: a GitLab worker crashing inside the regex engine (
puma_stderr.log).
You can also scan repository checkouts for planted payloads (oversized #+TODO: lines in .org files):
# Run inside a checkout of a suspect repository
rg -l --glob '**/*.org' '^\#\+(TODO|SEQ_TODO|TYP_TODO):.{500,}'
A crash is a reason to investigate, not proof of compromise. If you find signs of a successful attack, treat the server as compromised: code runs as the account GitLab runs as, so rotate CI/CD variables, runner tokens, deploy keys, and access tokens held on the server. Note that many instances do not ship puma_stderr.log by default, so confirm each rule’s required log sources before relying on it.
A self-managed GitLab holds your source code and often your deployment secrets, so a maximum-severity unauthenticated RCE on it is close to worst-case. Patch today, verify every instance (not just the one you think about), and keep a dated record of versions before and after for your auditors.
Need a hand getting every GitLab instance patched?
We help teams inventory self-managed GitLab, run the migration-bearing upgrades safely, and plan the upgrade path off unsupported versions. Book a free sanity check.
Self-managed GitLab to patch or upgrade?
Book a free 30-minute call. We'll confirm what's exposed, handle the migration-bearing upgrades, and plan a safe path off any unsupported version.