Dev.to Security 🔐 Cybersecurity 👁 0 📖 7 min read

GitLab CVE-2026-110264 Is a CVSS 10 RCE. How to Patch Self-Hosted GitLab Tonight

If you run self-managed GitLab, you are on a vulnerable version right now unless you upgraded in the last day. GitLab's October 21, 2026 critical patch release fixes CVE-2026-110264, an integer overflow in regex compilat

If you run self-managed GitLab, you are on a vulnerable version right now unless you upgraded in the last day. GitLab's October 21, 2026 critical patch release fixes CVE-2026-110264, an integer overflow in regex compilation that the advisory says lets an unauthenticated user run arbitrary code on the server "under certain conditions". CVSS 10.0 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H). The affected range starts at GitLab 7.0, CE and EE alike, and there is no workaround.

What follows is the release to install for your line, whether it runs migrations, the commands, and what to lock down if the upgrade has to wait until morning.

This is also the second CVSS 10 regex bug in GitLab in nine days. On October 12, GitLab fixed CVE-2026-97229, another integer overflow in the same regex engine, reported by the same HackerOne researcher (joaxcar). If you skipped that one because "we'll catch the next patch", this is the next patch.

GitLab.com is already patched. GitLab Dedicated tenants on 19.3.5-internal0 or 19.4.2-internal0 and later need no action. Everyone else on self-managed has work to do.

Which GitLab versions are affected by CVE-2026-110264

From the advisory, vulnerable means:

  • 7.0 up to (not including) 18.11.13
  • 19.0 before 19.0.10
  • 19.1 before 19.1.9
  • 19.2 before 19.2.9
  • 19.3 before 19.3.6
  • 19.4 before 19.4.3
  • 19.5 before 19.5.1

CE and EE are both affected. The advisory lists no workaround, so upgrading is the only official fix. The same release also patches 11 other CVEs, including two rated High (CVE-2026-15723, an OmniAuth-to-LDAP auto-linking authentication flaw at 8.2, and CVE-2026-112212, OAuth/OIDC discovery cache poisoning at 7.5), so this is worth installing even if you decide the RCE doesn't reach you.

Check your GitLab version first

On an Omnibus (Linux package) install, this gives you the version plus Ruby, Postgres and Gitaly details:

sudo gitlab-rake gitlab:env:info

Someone in the HN thread pointed out this is the one to run on each node if you're patching a fleet. Quicker options:

# Omnibus, no Rails boot
cat /opt/gitlab/embedded/service/gitlab-rails/VERSION

# From anywhere, with a token
curl -s --header "PRIVATE-TOKEN: $TOKEN" https://gitlab.example.com/api/v4/version

A few HN commenters still saw the in-app "strongly recommend upgrading" warning after moving to 19.5.1 or 19.4.3, and another replied that GitLab's update checker "has never worked very well". Trust the rake task over the banner.

The target release for each line, and which ones cost you downtime

This is the table I wanted when I opened the advisory. Migration info comes straight from its upgrade notes.

You are on Upgrade to Regular migrations Post-deploy migrations
19.5.x 19.5.1 No No
19.4.x 19.4.3 Yes Yes
19.3.x 19.3.6 Yes No
19.2.x 19.2.9 No No
19.1.x 19.1.9 No No
19.0.x 19.0.10 No No
18.11.x 18.11.13 No No
Anything older Upgrade path to one of the above Depends on the path Depends on the path

GitLab's wording: single-node instances will have downtime because migrations must finish before GitLab starts. Multi-node instances can patch with no downtime if you follow the zero-downtime upgrade procedure.

In practice, a patch-level bump with no migrations on a single node is the usual stop-reconfigure-start cycle. 19.4.3 and 19.3.6 are the ones where a big database makes the wait longer, so give those a wider maintenance window.

If you're on anything older than 18.11, there is no patch for your line. Plug your version into GitLab's upgrade path tool; depending on how far back you are, you'll have to walk several required upgrade stops before you reach 18.11.13 or newer. That's a longer evening, and one you were already overdue for.

The upgrade commands

Omnibus on Debian/Ubuntu, pinned to the exact version so apt doesn't surprise you:

sudo apt-get update
sudo apt-get install gitlab-ee=19.5.1-ee.0   # or gitlab-ce=19.5.1-ce.0
sudo gitlab-rake gitlab:env:info

RHEL-family:

sudo dnf install gitlab-ee-19.5.1-ee.0.el9

Docker: change the tag to gitlab/gitlab-ee:19.5.1-ee.0 (or the matching tag for your line), pull, recreate the container. Helm users: bump the chart to the version that ships your target GitLab release.

Swap 19.5.1 for whatever your row in the table says. Then check gitlab-ctl status and confirm background migrations finished under Admin > Monitoring > Background migrations before you call it done. For multi-node setups that can take an outage, GitLab's procedure is in Upgrade a multi-node instance with downtime.

What the bug actually is

GitLab's advisory is thin. It says "integer overflow when compiling a specially crafted regular expression" and stops there, so I went through the changelog and upstream Ruby for the rest.

The 19.5.1 changelog includes "Add Ruby regexp repeat ID overflow patch for 3.3, 3.4 and 4.0" for both Omnibus and the cloud-native images. That matches ruby/ruby PR 16801, merged April 29, 2026, titled "Reject overflowed repeat/null-check IDs in huge regexps". The bug, as described in the Omnibus backport: Onigmo stores range-repeat and null-check IDs in a signed 16-bit bytecode operand but counts them in an int. Past 32,767 the ID wraps negative, and at match time that negative ID indexes the repeat stack, which is an out-of-bounds write. The fix makes the compiler raise RegexpError ("too many range repeat") instead.

Two caveats. GitLab hasn't said this PR is CVE-2026-110264; the timing and wording line up, but that's my inference. And the older lines (19.1.9, 19.0.10, 18.11.13) list a different entry, "Add Ruby regexp repeat-range double-free patch for 3.3 and 3.4", so the fix isn't identical across versions.

The part that bothers me: the upstream fix landed on Ruby master (4.1) in April and wasn't on the 3.3, 3.4 or 4.0 branches when GitLab patched, so anything bundling those Rubies, GitLab included, needed its own backport. GitLab's arrived in October.

The trigger path is less clear. GitLab published two threat detections for self-managed instances: "Onigmo native worker crash" and "Org mode render error burst". They live in the gitlab-security-oss/tldr repository. The second name is a strong hint that the payload rides in an .org file that GitLab renders, and the 19.2 through 19.5 patches also bump gitlab-markup to 2.2.0. On HN, one commenter suggested the attack needs a public project that can hold the .org payload. Nobody confirmed whether that means the attacker needs push access. Treat that as an informed guess until the issue goes public, which GitLab schedules for 90 days after the patch.

For a sense of how practical these Onigmo overflows are: Rapid7's write-up of the October 12 bug reliably got command execution as the git user on the official gitlab/gitlab-ce:19.4.1-ce.0 image with ASLR on. The Puma worker crashes afterwards and the client sees a 502, so a 502 is not proof the attack failed.

If you can't upgrade tonight

There's no official mitigation, so everything here reduces exposure and nothing fixes the bug.

  1. Get it off the public internet. Put it behind a VPN, Tailscale, or an IP allowlist. A couple of HN self-hosters said they're counting on Tailscale to keep their instances out of reach.
  2. Turn off public projects. Admin > Settings > General > Visibility and access controls > Restricted visibility levels, tick Public. If the public-project theory is right, this removes the anonymous path.
  3. Disable open sign-ups and review recent new accounts and new public projects.
  4. Pull GitLab's two detections from gitlab-security-oss/tldr and run them against your logs. Repeated Puma worker crashes and bursts of org-mode render errors are what you're looking for.
  5. Schedule the upgrade for tomorrow morning, not "this sprint".

Self-hosting had a bad week

The same day, PHP put out 8.5.12, 8.4.27, 8.3.36 and 8.2.35 for two unauthenticated RCEs (CVE-2026-109618 and CVE-2026-109619, both CVSS v4.0 9.2). If you run both, you had two critical patches waiting before coffee.

The HN thread split the way you'd expect. One commenter argued that self-hosted enterprise software turns every library bug into a public GitLab advisory, while hosted platforms like GitHub can patch quietly. One commenter's Renovate config auto-merges GitLab patch releases. Others were wary of unattended updates; one remembered a nightly unattended yum cron job at a large company as "very iffy". Thomas Ptacek called CVSS a "Ouija board", and he has a point: Rapid7's working exploit for CVE-2026-97229 needed write access to a public project, despite the PR:N score, and Rapid7 says it doesn't know how the original report avoids that.

My take: self-hosting GitLab is fine if you treat patch releases like on-call pages. It gets dangerous when the instance sits on the internet, runs version 16-something, and the person who installed it left two years ago. The Ruby fix sat on master for almost six months before GitLab shipped a backport. Your instance shouldn't sit unpatched for six days.

How fast does your team actually patch self-hosted GitLab after a critical release: same day, same week, or "when someone notices"? And if you auto-update it, how many times has that blown up on you?

Sources

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.