# GitLab CVE-2026-110264: detection and response pack

Checker and hunting content for the critical GitLab flaw fixed on 21 October 2026, plus two related fixes from the same patch release.

| CVE | GitLab title | Severity | Affected (per GitLab) |
|---|---|---|---|
| **CVE-2026-110264** | Integer Overflow issue in Regular Expression Compiler impacts GitLab CE/EE | Critical, CVSS 10.0 (`AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H`) | all versions from 7.0 before 18.11.13; 19.0 < 19.0.10; 19.1 < 19.1.9; 19.2 < 19.2.9; 19.3 < 19.3.6; 19.4 < 19.4.3; 19.5 < 19.5.1 |
| CVE-2026-15723 | Improper Authentication issue in OmniAuth-to-LDAP auto-linking email lookup | High, CVSS 8.2 | 10.1 before 19.3.6; 19.4 < 19.4.3; 19.5 < 19.5.1. Only when OmniAuth SAML **and** LDAP auto-linking are both enabled. |
| CVE-2026-112212 | Cache Poisoning issue in OAuth/OIDC discovery endpoints | High, CVSS 7.5 | 18.3 before 19.3.6; 19.4 < 19.4.3; 19.5 < 19.5.1 |

GitLab says CVE-2026-110264 "under certain conditions, could have allowed an unauthenticated user to execute arbitrary code on the GitLab server due to integer overflow when compiling a specially crafted regular expression". Only self-managed installs need to act. GitLab.com is already patched, and GitLab Dedicated tenants on 19.3.5-internal0 / 19.4.2-internal0 or later already have the fix. GitLab gives no workaround. Upgrading is the only fix.

Sources:
- GitLab patch release post (primary): https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-5-1-released/
- GitLab TLDR detection rules (primary): https://gitlab.com/gitlab-security-oss/tldr
- The Hacker News, 21 Oct 2026: https://thehackernews.com/2026/10/critical-gitlab-flaw-cvss-100-could.html
- CVE record: https://www.cve.org/CVERecord?id=CVE-2026-110264 has no published record yet. The ID shows only as "reserved by a CNA".
- At the time of writing there are no public reports of exploitation, and the CVE is not in the CISA KEV catalogue (checked 21 Oct 2026). No NCSC, CISA or CERT-EU alert has been published.

## Fixed versions

| You run | Upgrade to at least | Also fixes 15723 / 112212? |
|---|---|---|
| 19.5.x | **19.5.1** | yes |
| 19.4.x | **19.4.3** | yes |
| 19.3.x | **19.3.6** | yes |
| 19.2.x | **19.2.9** (backport) | **no**. Move to 19.3.6+ for those |
| 19.1.x | **19.1.9** (backport) | **no** |
| 19.0.x | **19.0.10** (backport) | **no** |
| 7.0 to 18.11.x | **18.11.13** (backport). Older branches have to follow the upgrade path to 18.11.13 | **no** |

**If you patched on 12 October, you need to patch again.** The 12 October fix for CVE-2026-97229 brought servers to 19.4.2, 19.3.5 or 19.2.8 (per The Hacker News), and all three are below the 21 October fixed versions.

**Plan for downtime.** GitLab says 19.4.3 and 19.3.6 include regular database migrations, so single-node instances will be down while they run. Multi-node instances can use the zero-downtime procedure.

## Files

- `check-gitlab-110264.sh`: read-only Linux checker covering Omnibus, source installs and Docker containers/images.
- `gitlab-110264-hunting.kql`: Microsoft Sentinel and Defender XDR queries (Syslog, custom GitLab log tables, DeviceProcessEvents).
- `sigma/*.yml`: worker crash with Onigmo frames, Org-mode render timeouts, and a shell spawned by Puma, Sidekiq or Workhorse.
- `tests/run-mock-tests.sh`: offline tests that build fake roots in a temp directory.

## Usage

```bash
sudo bash check-gitlab-110264.sh                 # root reads gitlab.rb, logs and docker
sudo USE_RAKE=1 bash check-gitlab-110264.sh      # also try gitlab-rake gitlab:env:info (slow)
sudo LOG_LINES=500000 bash check-gitlab-110264.sh
GITLAB_ROOT=/mnt/gitlab-disk bash check-gitlab-110264.sh   # offline: a mounted disk or snapshot
```

The checker only reads files and runs `docker ps/images/exec cat`. It does not change configuration, restart anything or write files.

What it does:
1. Reads the version from `/opt/gitlab/version-manifest.txt`, then `gitlab-rails/VERSION`, `/home/git/gitlab/VERSION`, `gitlab-rake` (optional), and running `gitlab/gitlab-ce|ee` containers (it reads the manifest inside each one, or falls back to the image tag). It maps the version to the fixed release for its branch.
2. Gives a per-version verdict for CVE-2026-15723 and CVE-2026-112212, and checks `/etc/gitlab/gitlab.rb` for `ldap_enabled = true`, a `saml` OmniAuth provider **and** `omniauth_auto_link_ldap_user = true` together (the CVE-2026-15723 precondition).
3. Searches the logs. In `puma_stderr.log`, `sidekiq/current` and `gitlab-workhorse/current` it looks for `[BUG]`, segfault and bus-error lines and Onigmo/org-ruby frames, and for the Sidekiq line `A worker terminated, shutting down the cluster`. In `exceptions_json.log` it looks for `Timeout::Error` from `OtherMarkup` on `.org` files, and in the kernel log for segfaults of GitLab processes. It also counts user create/update calls in `production_json.log` and `api_json.log` as review items.

## Verdicts and exit codes

- **PATCHED**: the version is at or above the fixed release for its branch, or is 19.6 or later.
- **LIKELY VULNERABLE**: the version is below the fix for its branch, or is on a 7.0 to 18.10 branch that has no fix.
- **UNKNOWN**: the version can't be read.

| Exit | Meaning |
|---|---|
| 0 | Every GitLab install found is PATCHED, or no GitLab was found |
| 1 | At least one LIKELY VULNERABLE |
| 2 | At least one UNKNOWN, none vulnerable |
| 3 | Patched, but the log hunt found entries to review |

## GitLab's own detections

In its patch release post, GitLab published two **threat detections** for this CVE. They are part of its open-source TLDR framework, and each one includes a rule in Sigma format plus a raw log query. Treat them as the authoritative version. The Sigma in this pack borrows their logic and adds a process-creation rule.

- **Onigmo native worker crash**: [onigmo_native_worker_crash.md](https://gitlab.com/gitlab-security-oss/tldr/-/blob/main/Detections/platforms/GitLab/Vulnerability%20Detections/onigmo_native_worker_crash.md) (Sigma id `58461d1f-2ad8-41a8-861e-57c8b697657f`). It matches a `[BUG]` line in `puma_stderr.log` together with an `org-ruby` or Onigmo frame (`match_at`, `onig_search_gpos`, `onig_compile`, `compile_tree`, `compile_length_tree`, `rb_str_sub_bang`).
- **Org mode render error burst**: [org_mode_render_error_burst.md](https://gitlab.com/gitlab-security-oss/tldr/-/blob/main/Detections/platforms/GitLab/Vulnerability%20Detections/org_mode_render_error_burst.md). It fires on 5 or more `Timeout::Error` from `OtherMarkup` on `.org` files per client in 30 minutes, plus `Projects::BlobController#preview` calls where a `.org` `file_path` forces the Org renderer onto a non-Org file.
- **Admin account created or updated**: [admin_account_created_or_updated.md](https://gitlab.com/gitlab-security-oss/tldr/-/blob/main/Detections/platforms/GitLab/Threat%20Detections/admin_account_created_or_updated.md).

According to GitLab's TLDR write-up, the vulnerable path is org-ruby building a regex from an attacker-supplied Org-mode `#+TODO:` keyword. GitLab also says that the crash signal only corroborates other evidence: "a successful CVE-2026-110264 exploit is quiet and does not reliably crash". To scan repositories for payload files, TLDR suggests: `rg -l --glob '**/*.org' '^\#\+(TODO|SEQ_TODO|TYP_TODO):.{500,}'`.

**No IOCs.** GitLab has not published IPs, hashes or exploit strings, so this pack contains none.

## Response steps

1. **Upgrade** to the fixed version for your branch now (table above). Where you can, take the instance off the public internet until it's upgraded. TLDR notes that the unauthenticated path needs a public `.org` file that GitLab renders.
2. **Preserve evidence before you upgrade**: `/var/log/gitlab/` (puma, sidekiq, gitlab-workhorse, gitlab-rails `production_json`, `api_json`, `exceptions_json`, `application_json`, `audit_json`) and `/etc/gitlab/`.
3. **Run the hunts.** Look for crash lines, Org render timeouts, children of Puma or Sidekiq, new files owned by `git` in `/tmp`, changes to the `git` user's crontab or `~git/.ssh/authorized_keys`, and unexpected outbound connections.
4. **Review accounts**: newly created users, new or elevated admins (Admin Area > Users, filtered to admins and sorted by created date), unblocked users, admins with 2FA disabled, new personal, project and group access tokens, impersonation tokens, and new instance OAuth applications.
5. **If anything looks wrong, or the instance was internet-facing and unpatched, treat it as compromised and rotate**:
   - runner authentication tokens (re-register runners);
   - deploy keys and deploy tokens;
   - CI/CD variables at instance, group and project level, plus any cloud or registry credentials stored in them;
   - personal, project and group access tokens and OAuth application secrets;
   - `gitlab-secrets.json` keys, the SMTP, LDAP bind and object-storage credentials in `gitlab.rb`, and database passwords.
   On a confirmed compromise, rebuild the server from a known-good backup rather than cleaning it in place.
6. **CVE-2026-15723**: if SAML and LDAP auto-link are both enabled and you can't reach 19.3.6, 19.4.3 or 19.5.1, review recent identity links on LDAP-backed users in the Admin area for LDAP accounts that were linked to an unexpected SAML identity. Turning off `omniauth_auto_link_ldap_user` until you upgrade is a configuration change of our own; GitLab doesn't list it as a mitigation, so test it first.

## Limitations

- The verdict comes from the version only. The checker can't detect a hotpatched Onigmo or a custom build.
- Helm and Kubernetes installs aren't inspected. Check the image tag of the webservice and sidekiq pods yourself. The `gitlab.rb` check doesn't see Helm values, `GITLAB_OMNIBUS_CONFIG` or environment overrides.
- The log hunt reads standard Omnibus and source paths, and only the last 200,000 lines of each log by default. The Onigmo-frame check expects the multiline `[BUG]` report in the same file. Native crash reports often aren't shipped to SIEMs by default.
- The user/admin count is informational. Investigate it with the KQL Q4 query or the GitLab TLDR admin rule.
- Absence of findings is not proof of safety. GitLab hasn't disclosed the exact preconditions for reaching the vulnerable compiler.

## Testing done

- Run inside the real `gitlab/gitlab-ce:19.4.2-ce.0` image (the 12 Oct fix level): LIKELY VULNERABLE, exit 1. Inside `gitlab/gitlab-ce:19.5.1-ce.0`: PATCHED, exit 0.
- Run on the host against a running 19.4.2 container: the container was detected via `docker exec` and flagged, and the local image list was mapped correctly.
- `tests/run-mock-tests.sh`: 24/24 passed. This covers every fixed release and the release just below it, a no-fix branch (18.10, 16.0), 19.6, an unparseable version, no install, a synthetic `[BUG]` plus Onigmo crash log and Org timeout (exit 3), SAML+LDAP+auto-link detection, and commented-out config being ignored.
- `shellcheck` is clean, and `sigma check` reports no issues.
