On July 24, 2026, security researchers at depthfirst unveiled a critical Remote Code Execution (RCE) vulnerability in GitLab, publishing working exploit code for a flaw that GitLab had quietly patched six weeks earlier, on June 10. The vulnerability, which allows authenticated users to execute arbitrary commands as the git user on unpatched self-managed GitLab 18.11.3 servers, highlights significant concerns regarding vulnerability disclosure practices and the potential for silent fixes to leave organizations exposed. The exploit requires no administrator rights, no CI or runner access, no victim interaction, and no access to other projects, making it a highly potent threat for many GitLab deployments worldwide.
Discovery and Technical Details of the Exploit Chain
The journey to uncovering this critical RCE began with depthfirst’s autonomous security system, which flagged two distinct memory corruption bugs within Oj, a widely used Ruby JSON parser implemented primarily in native C. While the AI agent identified the underlying vulnerabilities, it was human researchers who meticulously chained these seemingly disparate bugs together to achieve full remote code execution. This collaborative effort between advanced automated analysis and expert human insight underscores a growing trend in sophisticated vulnerability research.
The technical core of the exploit revolves around how GitLab’s notebook renderer, specifically an in-tree gem named ipynbdiff, processes repository-controlled Jupyter Notebooks (.ipynb files). These notebooks, essentially JSON documents, are passed to Oj::Parser.usual.parse within a long-lived Puma worker process. This critical interaction means that attacker-controlled JSON data directly manipulates Oj’s manually managed C memory within the application process, creating a fertile ground for memory corruption.
Two distinct memory corruption vulnerabilities in Oj (versions 3.13.0 to 3.17.1) were leveraged:
- Nesting Stack Overflow: One bug allows an attacker to write past a fixed 1,024-byte nesting stack. By carefully crafting the input, this overflow can be used to control the parser’s
startcallback function, a crucial step towards diverting program execution. - Heap Pointer Leak: The second bug involves truncating a 65,565-byte object key to a mere 29 bytes due to an issue with a signed 16-bit field. Crucially, this truncation returns a live heap pointer, which GitLab’s diff renderer then inadvertently exposes in the generated commit diff. This leak provides attackers with vital information about the memory layout of the application, specifically the location of critical libraries like
libc.
With the ability to leak memory addresses and control a callback function, depthfirst researchers constructed a sophisticated attack chain. The exploit involves committing a series of specially crafted Jupyter notebooks. The first notebook, when its commit diff is opened, triggers the heap pointer leak, providing the attacker with the necessary memory addresses. Subsequent notebooks then leverage the nesting stack overflow to redirect the controlled callback to system(), a standard C library function that executes arbitrary shell commands. This allows the attacker to run commands as the git user on the compromised server.
GitLab’s Silent Patch and the CVE Controversy
Perhaps the most contentious aspect of this vulnerability is GitLab’s handling of the fix. The company patched the underlying Oj vulnerabilities by bumping the Oj gem to version 3.17.3 in its June 10 patch release. However, this fix was classified under "bug fixes" in the release notes for GitLab 19.0.2, rather than being highlighted in the dedicated security-fix table. Consequently, no Common Vulnerabilities and Exposures (CVE) identifier was assigned, no CVSS score was calculated, and there was no explicit mention of the critical Jupyter notebook-diff chain that enabled the RCE.

This lack of transparency had profound implications for system administrators and security teams. Operators who routinely triage patch releases often prioritize updates listed in the security table and those accompanied by CVEs and CVSS scores, which provide a standardized measure of severity and impact. By classifying this as a routine bug fix, GitLab inadvertently signaled to its users that the update was not urgent from a security perspective. This omission could have led many organizations to delay patching, leaving their self-managed instances vulnerable for weeks after the fix was technically available. The Hacker News has reached out to GitLab for clarification on why the fix was not classified as a security issue and whether a CVE will now be assigned, with responses pending.
Chronology of Events
The timeline of this vulnerability disclosure underscores the critical delay between the technical fix and public awareness:
- May 21, 2026: depthfirst reports the two memory corruption bugs in the Oj Ruby JSON parser to the Oj maintainer.
- May 27, 2026: The Oj maintainer merges the fixes for the reported bugs.
- June 4, 2026: Oj gem version 3.17.3, containing the fixes, is officially released.
- June 5, 2026: depthfirst reports the full RCE exploit chain, leveraging the Oj bugs within GitLab, to GitLab.
- June 8, 2026: GitLab independently reproduces and confirms the RCE vulnerability.
- June 10, 2026: GitLab releases patch versions (18.10.8, 18.11.5, 19.0.2) that include the Oj 3.17.3 update, but classifies the fix as a "bug fix" rather than a security patch, without assigning a CVE.
- July 24, 2026: depthfirst publicly discloses the vulnerability and publishes working exploit code on GitHub, forcing widespread awareness and immediate action from affected organizations.
- July 25, 2026: News outlets, including The Hacker News, report on the public disclosure and the implications of GitLab’s silent patching.
This timeline reveals a critical six-week window between GitLab’s patch release and the public disclosure of a functional exploit. During this period, organizations relying on GitLab’s release notes for security intelligence would have been unaware of the severity of the "bug fix" and the urgent need to update.
Affected Versions and Upgrade Guidance
The vulnerability impacts a wide range of GitLab CE/EE versions across all tiers, from Free to Ultimate. Ruby itself is not directly vulnerable; the issue lies specifically within the Oj gem and its integration within GitLab’s architecture.
Affected GitLab CE/EE versions:
- 15.2.0 to 18.10.7 (Fixed in 18.10.8)
- 18.11.0 to 18.11.4 (Fixed in 18.11.5)
- 19.0.0 to 19.0.1 (Fixed in 19.0.2)
Affected Oj gem versions:
- 3.13.0 to 3.17.1 (Fixed in 3.17.3)
Immediate Action Required:
Organizations operating self-managed GitLab instances are strongly urged to upgrade to the following patched versions:

18.10.818.11.519.0.2
Neither GitLab nor depthfirst has offered a viable workaround for those unable to immediately upgrade, underscoring the critical nature of applying these patches.
A crucial consideration for administrators deploying GitLab via container orchestration tools like Helm or Kubernetes Operators is to verify the GitLab version inside the Webservice image running Puma, not just the chart or Operator version. There can be discrepancies that leave instances vulnerable even if the orchestration layer appears up-to-date.
Furthermore, older GitLab versions, specifically those on patch trains 15.2 through 18.9, will receive no backports for this vulnerability. These versions sit outside GitLab’s security-maintained patch trains, meaning organizations running them must migrate to a currently supported release to mitigate the risk. This highlights the importance of adhering to vendor-supported lifecycles for critical software.
Implications for Self-Managed Instances
The impact of this RCE vulnerability on self-managed GitLab instances is severe. Since commands are executed as the git user, the attacker gains a high level of access within the GitLab application environment. The git user typically has read and write access to:
- Source Code Repositories: All project source code hosted on the instance, including sensitive intellectual property and proprietary algorithms.
- Rails Secrets: Configuration files containing sensitive secrets used by the GitLab application, such as database credentials, API keys, and encryption keys.
- Service Credentials: Credentials used to integrate with other services, potentially including cloud providers, CI/CD pipelines, and external repositories.
- CI/CD Data: Sensitive data related to continuous integration and continuous delivery pipelines, which might include deployment credentials, build artifacts, and environment variables.
- Internal Services: Access to internal services that the GitLab application can communicate with, potentially leading to lateral movement within the organization’s network.
The specific public exploit released by depthfirst is tailored for GitLab 18.11.3 on x86-64 architectures. It relies on specific gadget offsets, register states, and jemalloc behavior derived from that particular image. The recovered library base, crucial for the exploit, is only valid until the Puma master process restarts, meaning the exploit is not a "drop-in" for arbitrary targets. Porting the exploit to different GitLab versions or architectures requires significant effort due to the low-level memory manipulation involved. depthfirst estimates that the memory search phase of the exploit can take five to ten minutes on a fresh two-worker installation, potentially extending to one to two hours on longer-running instances with more complex memory layouts. This suggests that while porting is "real work," it is by no means impossible for a determined attacker.
The Broader Context of Vulnerability Disclosure
This incident serves as a stark reminder of the complexities and sensitivities surrounding vulnerability disclosure. The decision by a vendor to classify a critical RCE fix as a mere "bug fix" can have far-reaching consequences, potentially leaving a vast user base unknowingly exposed to severe risks. Transparent communication, including the timely assignment of CVEs and clear security advisories, is paramount for enabling organizations to assess risks accurately and prioritize patching efforts effectively.
The involvement of an AI agent in the initial discovery of the Oj bugs, as noted by depthfirst (who also linked to an article about an AI agent uncovering zero-days), highlights the evolving landscape of cybersecurity research. As AI tools become more sophisticated, they are increasingly capable of identifying complex vulnerabilities that might elude traditional manual analysis or simpler automated scanners. This trend necessitates that software vendors and security teams adapt their disclosure and patching strategies to keep pace with these advanced discovery methods.

Moreover, the incident underscores the responsibility of organizations running self-managed software to maintain vigilance. Relying solely on security tables for patch prioritization can be perilous when critical vulnerabilities are miscategorified. A comprehensive patch management strategy should ideally involve reviewing all changes in patch releases, especially for core components and dependencies, and proactively seeking additional context from security researchers or vendor communications.
Recommendations and Future Outlook
In light of this disclosure, the immediate priority for all GitLab self-managed instance operators is to verify their current version and apply the necessary patches without delay. For those on unsupported older versions, an upgrade to a currently maintained release is imperative.
Looking forward, this event will likely prompt discussions within the cybersecurity community and among software vendors regarding best practices for vulnerability classification and disclosure. There is a clear need for standardized criteria and perhaps third-party oversight or independent review for critical fixes, especially when a vendor’s internal classification might contradict the actual severity. The absence of a CVE for such a severe vulnerability, particularly after an exploit becomes public, is a significant oversight that could be rectified by GitLab retroactively assigning one.
The ongoing inquiries from The Hacker News to GitLab regarding the classification and CVE assignment, and to depthfirst about exploit portability, are crucial for shedding more light on this situation and fostering improved transparency in the future. As the digital threat landscape continues to evolve, the collective security posture of the internet relies heavily on diligent vulnerability discovery, responsible disclosure, and proactive patching practices from both vendors and users alike.
