Back to Blog
GitLabCI/CDCybersecurityVulnerability ManagementDevSecOps

GitLab CVE-2026-110264 and CVE-2023-5009: Who Is Exposed and How to Upgrade Self-Managed GitLab

CVE-2023-5009 and CVE-2023-3932 were re-rated High today. Any GitLab old enough to have them also has CVE-2026-110264, a CVSS 10 flaw with no workaround. How to check and upgrade.

P
Davi Nunes
October 28, 202610 min read

On 28 October 2026, two GitLab vulnerabilities from 2023 were re-rated. CVE-2023-5009 and CVE-2023-3932, which let an attacker run pipeline jobs as another user, are now both scored 8.2 (High). If they have just appeared in your vulnerability scanner or your security feed, the re-rating is why.

Nothing about these two bugs is new. They were fixed in 2023, and GitLab's hosted service has been safe from them ever since. What makes them worth your attention is what they say about your server: any self-managed GitLab still old enough to have them is also exposed to CVE-2026-110264, a flaw rated 10 out of 10 that GitLab fixed on 21 October 2026. It lets an attacker with no account run code on the GitLab server, it affects every self-managed release since 2014, and there is no workaround.

Below: what each flaw does, who is exposed, how to check your real version, and how to get an old instance to a fixed release. That last part is the hard one, because GitLab will not let you get there in one jump.

CVE-2023-5009 and CVE-2023-3932: Pipelines That Run as Someone Else

Both bugs are in scan execution policies, an Enterprise Edition feature that runs security scans on a schedule.

A scheduled pipeline has to run as some user. In the affected versions, GitLab chose the user who last changed the policy file, and it read that from the Git history, which anyone who can push is free to write. An attacker with push access to a policy project set their Git author to the victim's name, pushed a trivial change, and the next scheduled scan ran as the victim. Picked up by a runner the attacker controlled, that job carried the victim's job token, which was enough to clone the victim's private projects.

  • CVE-2023-3932 is the original bug, present in Enterprise Edition from 13.12. It was fixed in August 2023 in 16.0.8, 16.1.3 and 16.2.2, which moved policy pipelines to a dedicated bot user.
  • CVE-2023-5009 is a bypass of that fix, published in September 2023. A maintainer could remove the bot from the project, or forge the history of a policy project brought in with direct transfer, and get pipelines running as a real user again. It was fixed in 16.2.7 and 16.3.4.

Both need an account on the instance and some preparation, which is why they are rated High rather than Critical, and both affect Enterprise Edition only.

CVE-2026-110264: The Flaw That Matters Now

On 21 October 2026, GitLab shipped an emergency patch release for CVE-2026-110264, rated 10.0, the maximum score. Compiling a specially crafted regular expression overflows an integer inside the regular-expression engine and corrupts memory, and under certain conditions an attacker with no account can turn that into code execution on the GitLab server.

  • Every self-managed release since GitLab 7.0, published in 2014, is affected, Community and Enterprise Edition alike.
  • There is no workaround. No setting turns the vulnerable code off. Upgrading is the fix.
  • GitLab's hosted service and its dedicated single-tenant offering are already patched. If you only use those, there is nothing to do.
  • The exact conditions are not public. GitLab's own detection guidance points at the rendering of Org-mode (.org) files and at native crashes in the regular-expression engine, and independent analyses describe a crafted file in a public project as the way in.

Fixed versions: 18.11.13, 19.0.10, 19.1.9, 19.2.9, 19.3.6, 19.4.3 and 19.5.1. Anything older on those lines is vulnerable, and so is every release before 18.11, where no fix exists at all.

One trap: the 12 October patches do not cover it. That day GitLab released 19.4.2, 19.3.5 and 19.2.8 for a different 10.0 flaw, CVE-2026-97229, a crafted regular expression in a CI/CD configuration. Teams that patched promptly that week are still exposed to the 21 October bug and need to upgrade again.

How Big This Is

  • Three maximum-severity flaws in six weeks. Before the two October regular-expression bugs, GitLab fixed CVE-2026-85706 in September, a file read through the repository commits API that needs no login, also rated 10.0. Attacks started within a day of the fix, and it was added to the official catalogue of vulnerabilities known to be exploited.
  • Twelve years of releases. The affected range for CVE-2026-110264 starts in 2014, so every self-managed instance not upgraded since 21 October is in scope.
  • More than 80,000 GitLab servers are visible from the internet, by one count taken the day the fix came out. Each one that has not been upgraded since is a candidate.
  • Old instances are common. A GitLab server is often set up once by a team that has since moved on, then left running because everything depends on it. An instance that still has the 2023 bugs has missed more than three years of security releases.

The honest caveat: at the time of writing, there are no confirmed reports of CVE-2026-110264 being exploited, and code published online claiming to exploit it has not been verified. The September flaw shows how quickly that changes: attackers were using it within a day of the fix.

A GitLab server is not just another web application. It holds your source code, the CI/CD variables with your deployment credentials, your container registry, and the tokens your runners use to reach production. Code execution on it is a short path to everything it deploys to.

Not sure which version you run, or how far behind it is? Request a free GitLab security assessment and our security team will check it with you.

Step 1: Check Your Real Version

In the web interface, sign in and select Help > Help at the bottom of the left sidebar. The version is at the top of the page. On the server:

bash
# Linux package installations
head -1 /opt/gitlab/version-manifest.txt
sudo gitlab-rake gitlab:env:info

The first command prints the edition and the version, for example gitlab-ee 19.5.1. For other installation types:

bash
# Docker
docker exec <container> head -1 /opt/gitlab/version-manifest.txt

# Kubernetes with the Helm chart: the APP VERSION column is the GitLab version
helm list -A | grep -i gitlab

Or through the API, with a personal access token:

bash
curl --header "PRIVATE-TOKEN: <your-token>" https://gitlab.example.com/api/v4/version

Then place yourself:

  • 18.11.13, 19.0.10, 19.1.9, 19.2.9, 19.3.6, 19.4.3, 19.5.1, or later on the same line: patched for CVE-2026-110264. Nothing urgent.
  • 18.11 to 19.5, below the fixed release for your line: one patch upgrade. Go to Step 3.
  • Anything older than 18.11: your line has no fix. You need an upgrade path. Go to Step 2.
  • Enterprise Edition older than 16.3.4: you also have CVE-2023-5009, and you are on the long path.

Step 2: Plan the Path If You Are Behind

GitLab does not let you jump from an old version straight to a current one. Its database changes are spread across required upgrade stops: versions you must land on and let finish their background migrations before you move on. Skipping one can leave the database in a state the next version cannot handle.

The required stops on the way to a fixed release:

  • GitLab 16: 16.3.9, 16.7.10 and 16.11.10
  • GitLab 17: 17.3.7, 17.5.5, 17.8.7 and 17.11.7
  • GitLab 18: the latest patch of 18.2, 18.5 and 18.8, then 18.11.13 or later
  • Conditional stops: some instances also need 16.0.10, 16.1.8, 16.2.11 or 17.1.8, depending on their data. GitLab's Upgrade Path tool tells you which apply to yours.

An instance on 16.2 therefore needs around a dozen upgrades to reach a fixed release, each followed by a wait. That is a planned maintenance window, not a Friday-evening package update.

Before the first step:

  • Take a backup, and keep the secrets file with it. sudo gitlab-backup create does not include /etc/gitlab/gitlab-secrets.json or /etc/gitlab/gitlab.rb. Without the secrets file, a restored backup cannot decrypt your CI/CD variables. Copy both somewhere safe.
  • Check the database and the operating system. Newer major versions require newer PostgreSQL, and an instance this old may run on an operating system the current packages no longer support. Find out before the maintenance window, not during it.
  • Rehearse on a copy. Restore the backup onto a throwaway server and run the whole path there first. You learn how long each step takes and where it breaks, without your team watching.

Step 3: Upgrade

For each stop on the path, or for the single patch upgrade if you are already on 18.11 or newer:

bash
# Linux package on Debian and Ubuntu (Enterprise Edition;
# for Community Edition use gitlab-ce=<version>-ce.0)
sudo apt update
sudo apt install gitlab-ee=18.11.13-ee.0

On Docker, change the image tag, for example to gitlab/gitlab-ee:18.11.13-ee.0, and recreate the container with the same volumes. The Helm chart has its own version numbers: pick the chart release that ships the GitLab version you need and run helm upgrade with it.

Between stops, open Admin > Monitoring > Background migrations and wait until nothing is queued or running. Only then go to the next one. When you reach the fixed release, run the built-in health check:

bash
sudo gitlab-rake gitlab:check SANITIZE=true

On a single server, expect downtime during each upgrade while the database migrations run.

Step 4: Until You Can Upgrade

If the path is long, these reduce your exposure while you work through it. None of them is a fix.

  • Take the instance off the public internet. Put it behind a VPN or an IP allowlist. Most GitLab servers only need to be reachable by the team and its runners.
  • Turn off open sign-up under Admin > Settings > General > Sign-up restrictions, so strangers cannot create an account.
  • Restrict the Public visibility level under Admin > Settings > General > Visibility and access controls, so nothing on the instance can be viewed without signing in.
  • For CVE-2023-5009 specifically, GitLab's documented mitigation is to keep at most one of direct transfer and security policies turned on.

Step 5: Check Whether Someone Got There First

An instance that stayed vulnerable for a long time should be checked, not just upgraded. An upgrade closes the door. It does not remove anyone who already came in.

  • Native crashes of the web workers. Failed attempts against a memory-corruption bug tend to crash the process, and Ruby writes a [BUG] report when that happens. On Linux package installations:
bash
sudo zgrep -l '\[BUG\]' /var/log/gitlab/puma/puma_stderr.log*
  • Errors rendering .org files, especially in bursts from a single address, and .org files nobody can account for in public projects.
  • Runners you did not register. The 2023 bugs relied on a runner the attacker controlled. Review Admin > CI/CD > Runners for anything unfamiliar.
  • Pipelines started by people who would never start them, particularly scheduled security scans.
  • Unexpected processes or outbound connections from the GitLab service account.

If anything looks wrong, treat it as an incident. Preserve the logs and a disk snapshot. Rotate everything the server holds: CI/CD variables, runner tokens, deploy keys and tokens, personal access tokens and integration credentials. Then rebuild from a clean installation rather than cleaning the old one in place.

The Real Problem Is the GitLab Nobody Owns

Upgrading GitLab once is not hard. Keeping it current is: a release every month, patch releases in between, and required stops that pile up the longer you wait. The instances that still have 2023 bugs in 2026 are rarely there because someone decided to stay. They are there because nobody owned the upgrades.

Your GitLab server holds the keys to everything it deploys. It deserves the same patching discipline as production, because in practice it is production.

Get a Free GitLab Security Assessment

If you run self-managed GitLab and are not sure how far behind it is, what is exposed, or how to bring it up to date without breaking it, our security team will work it out with you at no cost.

The free assessment covers:

  • Your real version and edition, checked against every critical GitLab advisory, including CVE-2026-110264, CVE-2026-97229, CVE-2026-85706 and the 2023 pipeline flaws
  • Your upgrade path, with every required stop, the database and operating system changes along the way, and a realistic downtime estimate
  • An exposure review: what is reachable from the internet, sign-up and visibility settings, registered runners, and where your CI/CD secrets live

You get a written list of what is exposed and what to do about it, with no obligation attached.

Request your free GitLab security assessment, or read more about our cybersecurity practice, how our CI/CD consulting and DevSecOps work keeps pipelines patched and their secrets out of reach, and how to build a secure CI/CD pipeline from the start.

GitLab CVE-2026-110264: How to Fix | Privum Consulting