GitLab Alert: Public Exploit for Critical RCE Vulnerability, the Fix Was Hidden in an Ordinary Bug
Vulnerabilities

Illustrative image generated with AI

GitLab Alert: Public Exploit for Critical RCE Vulnerability, the Fix Was Hidden in an Ordinary Bug

A public exploit targets a critical GitLab RCE flaw via Jupyter notebooks. Learn about the hidden bug fix and patch your self-hosted instances.

Text generated by artificial intelligence, published without human review. AI transparency

Introduction

On July 24, 2026, the depthfirst research team published a complete exploit for a critical Remote Code Execution (RCE) vulnerability affecting self-hosted GitLab Community Edition (CE) and Enterprise Edition (EE). The flaw allows an authenticated user with push permissions to obtain a shell on the server with the privileges of the git process, simply by uploading a malicious Jupyter notebook. The most alarming detail is that GitLab had already released a fix on June 10, but classified it as an ordinary “bug fix”, omitting it from the security updates table. Consequently, many administrators may not have applied the patch, leaving thousands of instances exposed to an attack now facilitated by the public availability of the offensive code.

Technical Analysis

The vulnerability lies in two distinct memory corruption bugs in the native JSON parser Oj (Optimized JSON), a widely used Ruby gem. Versions of Oj prior to 3.17.3 do not correctly handle certain complex JSON structures, causing overflows and out-of-bounds reads. In GitLab, the ipynbdiff component — responsible for displaying differences between Jupyter notebook versions (.ipynb files) — internally uses Oj::Parser.usual.parse to process file content. An attacker with write access to a repository can craft a specially manipulated notebook and push it. When any user (including the attacker) views the notebook diff in the web interface, the vulnerable parser is executed and the payload within the file takes control.

The exploit released by depthfirst operates in two phases:

  1. Memory Leak: leveraging the first bug, the payload forces the parser to disclose memory addresses, bypassing ASLR (Address Space Layout Randomization).
  2. Arbitrary Execution: through heap spraying, shellcode is injected that modifies the execution flow of the Puma process (GitLab's application server) to execute commands chosen by the attacker.

The exploit is optimized for GitLab 18.11.3 on x86-64 architecture. On fresh installations the process requires a few minutes, while on long-running servers it can take hours due to heap memory fragmentation. Adaptation to other x86-64 builds is relatively simple (requiring only updated offsets and ROP gadgets), while porting to ARM64 involves significant rewriting.

The vulnerable GitLab versions are:

  • from 15.2.0 to 18.10.7
  • from 18.11.0 to 18.11.4
  • from 19.0.0 to 19.0.1

The fixes were introduced with the release of Oj 3.17.3 (June 4, 2026) and integrated into subsequent GitLab versions: 18.10.8, 18.11.5, and 19.0.2. Inside GitLab, ipynbdiff was also modified to use more robust parsers, eliminating the attack path.

Impact

Obtaining a shell as the git user on the GitLab server means almost total compromise of the platform. The attacker can:

  • Read and alter all hosted source code.
  • Access Rails secrets (encryption keys, session tokens) and service credentials (database, external integrations).
  • Harvest CI/CD environment variables, access tokens, and potentially move laterally to other services reachable from the host.
  • Modify CI/CD pipelines to deploy malicious payloads or exfiltrate data at scale.

Even though the attacked process is confined to the git user, the extent of damage depends on the isolation of the container or virtual machine on which GitLab runs. Instances running on unsupported versions (from 15.2 to 18.9) receive no backports: they remain vulnerable without any official fix, unless forced to migrate to a supported release. As of July 24, no active in-the-wild attacks had been recorded, but the exploit publication radically changes the threat landscape.

Mitigation

The absolute priority is to immediately apply the update to one of the versions containing the fix:

  • GitLab 18.10.8
  • GitLab 18.11.5
  • GitLab 19.0.2 (or newer)

Administrators who rely solely on the summary table of “security fixes” in release posts may not have installed the June 10 patch, since GitLab labeled it as a “bug fix”. It is therefore recommended to manually verify the running version, especially in environments with selective update policies.

For Helm or Operator deployments on Kubernetes, it is crucial to check the image version of the Webservice component (which runs Puma), not the chart or Operator version, as the latter might mask an obsolete component.

There is no official or validated workaround for those who cannot update immediately. Restricting repository access and notebook diff rendering only to strictly trusted users reduces the attack surface, but GitLab does not provide a documented option to fully disable the vulnerable path. For specific guidance, contact GitLab support.

FAQ

1. Which GitLab versions are exactly affected?
All self-managed versions from 15.2.0 up to 18.10.7, from 18.11.0 to 18.11.4, and from 19.0.0 to 19.0.1 are vulnerable. Releases prior to 15.2.0 use different parsers and are not exposed. Versions 18.10.8, 18.11.5, 19.0.2 and later contain the fix.

2. How can I check if my instance has already been compromised?
No public indicators of compromise (IoC) have been released at this time. However, given the nature of the attack (arbitrary command execution as git), it is advisable to monitor system logs for unusual processes, anomalous outbound network connections, or unexpected changes to GitLab configuration files. The absence of alerts does not guarantee a clean system: prompt updating remains the essential countermeasure.

3. Why didn’t GitLab issue a security advisory with a CVE?
At the time of exploit publication, GitLab had not yet commented on the decision to classify the fix as an “ordinary bug”. Typically vulnerabilities of this severity receive a CVE identifier and are listed in the security section of the release post. The lack of transparency has likely extended the exposure period for many administrators. Further official communications are expected.

Read next

Sources

This article is an original reworking based on the sources below.

Related topicsGitLab RCEGitLab vulnerabilityJupyter notebook exploitOj JSON parser bugself-hosted GitLab securityGitLab patchremote code execution
Back to home