Critical GitLab RCE Vulnerabilities Patched in Multiple Products
Key Takeaways A critical exploit chain involving two long-standing memory-safety vulnerabilities in the Ruby JSON parsing library, Oj, has been discovered. These flaws could be combined to achieve...
Key Takeaways
- A critical exploit chain involving two long-standing memory-safety vulnerabilities in the Ruby JSON parsing library, Oj, has been discovered.
- These flaws could be combined to achieve remote code execution (RCE) on default GitLab installations.
- The vulnerabilities allowed authenticated users with push and diff-view access to execute arbitrary commands as the “git” system user.
- GitLab has released patches across multiple versions, and self-managed instances must upgrade immediately.
- The issues underscore the hidden risks of memory-unsafe native extensions within otherwise memory-safe applications.
A sophisticated exploit chain has been uncovered in GitLab, demonstrating how two previously undetected memory-safety vulnerabilities within the Oj Ruby JSON parsing library could be leveraged for remote code execution (RCE) on standard GitLab setups. This critical flaw potentially exposes sensitive data such as source code, Rails secrets, and internal services.
Table Of Content
The discovery emerged from the Open Defense Initiative, where Depthfirst researcher Yuhang Wu utilized an automated analysis system to scrutinize Oj. Oj is a high-performance, C-based JSON parser extensively used in Ruby applications, including GitLab.
The scan identified 18 prioritized vulnerabilities, seven of which were memory-safety bugs. Remarkably, two of these memory-safety flaws had remained dormant within Oj for nearly five years before being weaponized into a functional exploit chain.
Specifically, the two critical flaws were an unchecked nesting-stack write occurring in Oj::Parser.usual.parse and an insecure 16-bit key-length narrowing that resulted in a heap pointer leak.
Individually, these vulnerabilities posed limited threats: one offered only a repetitive one-byte write primitive, while the other exposed a fixed 29-byte memory slice. However, when chained together through precise heap-allocator manipulation, attackers gained complete control over a callback pointer and a method to bypass Address Space Layout Randomization (ASLR), ultimately enabling arbitrary code execution under the privileges of the “git” system user.
GitLab Vulnerabilities Enable Code Execution
GitLab’s rendering of human-readable diffs for Jupyter Notebook (.ipynb) files relies on an embedded gem called ipynbdiff. Before generating these diffs, the gem parses each notebook revision using Oj’s native parser to confirm the JSON contains a “cells” field.
Since a notebook file is fundamentally a JSON document, any authenticated user capable of pushing commits and viewing a commit diff could inject malicious JSON structures into this parsing process.
The exploit involved pushing two specially crafted notebook files within a single commit-diff request. The first file, designed with an excessively deep nesting structure, exploited the unchecked stack write to redirect an internal buffer pointer. Subsequent heap operations caused a Ruby Array’s memory to overlap with a parser callback pointer, allowing attackers to implant a chosen address into p->start.
A second heap-pointer leak, subtly embedded within an oversized JSON object key and rendered in the diff’s HTML output, provided attackers with the necessary address to calculate the memory locations of core libraries like libc and libruby, thereby circumventing ASLR protections.
Because Puma, GitLab’s Ruby application server, operates with multiple threads sharing a single native parser instance per worker, both malicious files were processed by the same vulnerable parser within a single request. This allowed the second file to trigger the corrupted callback, leading to the execution of a shell command via system().
Unlike previous GitLab remote code execution vulnerabilities that often relied on server-side request forgery (SSRF) against internal Redis instances, this new chain completely bypassed GitLab’s modern SSRF defenses. It achieved this by directly attacking a native, memory-unsafe dependency embedded within otherwise memory-safe Ruby code.
Crucially, any project member with standard push and diff-view access could trigger this exploit chain without requiring administrator rights, CI/CD access, or any interaction from a victim. This makes the vulnerability particularly dangerous for shared or multi-tenant self-managed GitLab instances.
Successful exploitation granted command execution privileges as the “git” account, which powers GitLab’s Puma workers. This could potentially expose repository source code, Rails application secrets, service credentials, and any internal services accessible from the GitLab host. The potential consequences include data theft, code tampering, and lateral movement within the network, according to Depthfirst in a statement to CybersecurityNews.
Affected Versions and Fixes
| Component | Affected Versions | First Fixed Release |
|---|---|---|
| GitLab CE/EE | 15.2.0–18.10.7 | 18.10.8 |
| GitLab CE/EE | 18.11.0–18.11.4 | 18.11.5 |
| GitLab CE/EE | 19.0.0–19.0.1 | 19.0.2 |
| Oj gem | 3.13.0–3.17.1 | 3.17.3 |
GitLab.com was already patched at disclosure, and Dedicated customers are not required to take any action. However, operators of self-managed GitLab instances running within the affected version ranges must upgrade immediately.
The vulnerable Oj parser code was introduced in August 2021, and GitLab began utilizing the affected parsing call in July 2022, starting with GitLab version 15.2.0.
The researcher initially reported the core Oj bugs on May 21, 2026. Oj subsequently merged fixes on May 27, after the flaws had persisted for 1,753 days, with Oj 3.17.3 published on June 4. The GitLab-specific exploit chain was reported on June 5, confirmed on June 8, and patched on June 10, 2026, across the 19.0.2, 18.11.5, and 18.10.8 releases.
Beyond the two vulnerabilities used in this specific exploit chain, the same research effort yielded nine additional CVEs for Oj. These range from stack and heap buffer overflows to multiple use-after-free conditions in SAJ callbacks and document iterators, a negative-size memcpy, and a large-file integer overflow. This extensive list highlights the profound risk that memory-corruption issues can pose when hidden within native extensions bundled with otherwise “safe” Ruby applications.
What You Should Do
- Immediately upgrade all self-managed GitLab CE/EE instances to the latest patched versions: 18.10.8, 18.11.5, or 19.0.2, depending on your current branch.
- Verify that the Oj gem in your Ruby environments is updated to version 3.17.3 or later.
- Conduct an audit of your Ruby dependency trees, paying close attention to any native C extensions. These extensions can introduce memory-safety risks that undermine the overall security of your Ruby application stack.
- Monitor official GitLab security advisories for further updates or related vulnerability disclosures.
Disclaimer: HackersRadar reports on cybersecurity threats and incidents for informational and awareness purposes only. We do not engage in hacking activities, data exfiltration, or the hosting or distribution of stolen or leaked information. All content is based on publicly available sources.



No Comment! Be the first one.