Full Report
A newly disclosed GitLab vulnerability has revealed how two long-standing memory-safety flaws in the widely used Ruby JSON parsing library, Oj, can be combined to achieve remote code execution on default GitLab installations. The research, led by Yuhang Wu as part of the Open Defense Initiative, demonstrates how attackers could exploit Jupyter Notebook file processing to execute arbitrary commands, potentially exposing repositories, application secrets, and internal services. Yuhang Wu Discovers GitLab Vulnerability in Oj Parser As part of the Open Defense Initiative, Depthfirst researcher Yuhang Wu used an automated analysis system to examine Oj, a high-performance native C-based JSON parser used across Ruby applications, including GitLab. The analysis identified 18 prioritised vulnerabilities, seven of which were memory-safety issues. Two of these flaws had remained undetected for nearly five years before being combined into a working exploit chain. The vulnerabilities included an unchecked nesting-stack write in Oj::Parser.usual.parse and an unsafe 16-bit key-length narrowing issue that leaked a heap pointer. Individually, the bugs appeared limited, offering only a repeated one-byte write primitive and a fixed 29-byte memory disclosure. However, by carefully manipulating heap allocation, the exploit gained control of a callback pointer and bypassed Address Space Layout Randomisation (ASLR), enabling arbitrary code execution as the "git" system user. Jupyter Notebook Processing Creates Attack Path The GitLab vulnerability stems from the platform's handling of Jupyter Notebook (.ipynb) files. GitLab uses an in-tree gem called ipynbdiff to generate human-readable notebook differences. Before displaying a diff, the gem parses each notebook with Oj to verify that the JSON contains a "cells" field. Because Jupyter Notebook files are JSON documents, any authenticated user with permission to push commits and view commit differences could submit specially crafted notebook files. The exploit chain used two malicious notebook files in a single commit-diff request. The first abused excessive nesting depth to corrupt an internal buffer pointer, eventually allowing a Ruby Array to overlap with a parser callback pointer and overwrite p->start with an attacker-controlled address. The second file leaked a heap pointer through an oversized JSON object key that appeared in the generated HTML diff. This disclosed the memory addresses of libraries such as libc and libruby, defeating ASLR. Since GitLab's Puma application server processes multiple threads using a shared parser instance, both files were handled by the same vulnerable parser, allowing the corrupted callback to invoke system() and execute shell commands. Unlike previous GitLab remote code execution vulnerabilities that depended on server-side request forgery (SSRF) against Redis, this GitLab vulnerability bypassed modern SSRF protections by targeting a native memory-unsafe dependency within Ruby code. Any project member with standard push and diff-view permissions could trigger the attack without administrator privileges, CI/CD access or user interaction. According to Depthfirst, successful exploitation could expose repository source code, Rails secrets, service credentials, and internal services, creating risks of data theft, code tampering, and lateral movement. Affected Versions and Available Fixes The GitLab vulnerability affects GitLab CE/EE versions 15.2.0-18.10.7, fixed in 18.10.8; 18.11.0-18.11.4, fixed in 18.11.5; and 19.0.0-19.0.1, fixed in 19.0.2. The Oj gem is affected from versions 3.13.0-3.17.1 and fixed in version 3.17.3. GitLab.com had already been patched before disclosure, while GitLab Dedicated customers required no action. Self-managed deployments running affected versions should upgrade immediately. The vulnerable Oj code was introduced in August 2021, with GitLab adopting the affected parser in July 2022 through version 15.2.0. Yuhang Wu reported the Oj flaws on 21 May 2026 after they had remained undiscovered for 1,753 days. Oj merged fixes on 27 May, released version 3.17.3 on 4 June, and the GitLab exploit chain was reported on 5 June, confirmed on 8 June and patched on 10 June 2026 in releases 19.0.2, 18.11.5 and 18.10.8. The same research also uncovered nine additional published CVEs affecting Oj, including stack and heap buffer overflows, use-after-free vulnerabilities, a negative-size memcpy flaw and a large-file integer overflow, highlighting the risks posed by memory-unsafe native extensions in Ruby applications.
Analysis Summary
# Vulnerability: Remote Code Execution in GitLab via Oj Parser Memory-Safety Flaws
## CVE Details
- **CVE ID:** Not explicitly listed in the text for the primary exploit chain (mentions 9 additional related CVEs affecting Oj).
- **CVSS Score:** Not specified (Likely Critical based on RCE impact).
- **CWE:** CWE-119 (Memory Corruption), CWE-190 (Integer Narrowing), CWE-674 (Uncontrolled Recursion).
## Affected Systems
- **Products:**
- GitLab Community Edition (CE)
- GitLab Enterprise Edition (EE)
- Oj (Optimized JSON) Ruby Gem
- **Versions:**
- **GitLab:** 15.2.0 to 18.10.7; 18.11.0 to 18.11.4; 19.0.0 to 19.0.1.
- **Oj Gem:** 3.13.0 to 3.17.1.
- **Configurations:** Default installations of GitLab self-managed instances.
## Vulnerability Description
The vulnerability is a multi-stage exploit chain involving two memory-safety flaws in the `Oj` JSON parser, a C-based native extension for Ruby.
1. **Nesting-Stack Write:** An unchecked nesting depth in `Oj::Parser.usual.parse` allows for a buffer pointer corruption.
2. **Integer Narrowing:** A 16-bit key-length narrowing issue allows for a fixed 29-byte memory disclosure, leaking heap pointers and bypassing ASLR.
3. **The Chain:** When GitLab processes Jupyter Notebook (`.ipynb`) files via the `ipynbdiff` gem, the shared parser instance in the Puma application server can be manipulated. An attacker can overlap a Ruby Array with a parser callback pointer, eventually redirecting execution to `system()` to run arbitrary shell commands.
## Exploitation
- **Status:** PoC demonstrated by researchers; exploited in controlled vulnerability research environments.
- **Complexity:** High (Requires precise heap manipulation and bypassing ASLR).
- **Attack Vector:** Network (Authenticated). Any user with permissions to push commits and view commit differences can trigger the flaw via crafted `.ipynb` files.
## Impact
- **Confidentiality:** High (Access to repository source code, Rails secrets, and service credentials).
- **Integrity:** High (Potential for code tampering and unauthorized command execution).
- **Availability:** High (Potential for system-level disruption as the "git" user).
## Remediation
### Patches
- **GitLab:** Update to versions **18.10.8**, **18.11.5**, or **19.0.2**.
- **Oj Gem:** Update to version **3.17.3** or higher.
### Workarounds
- No specific software workarounds (e.g., disabling Jupyter diffs) were mentioned; immediate patching is the recommended course of action.
- Ensure GitLab.com and GitLab Dedicated are used, as they were patched prior to public disclosure.
## Detection
- **Indicators of Compromise:** Unusual activity from the "git" system user; unexpected shell commands being spawned by the Puma process.
- **Detection Methods:** Monitor for commit-diff requests involving multiple suspicious Jupyter Notebook files in a single commit. Audit logs for crashes in native Ruby extensions (segmentation faults) which may indicate failed exploitation attempts.
## References
- [hXXps://thecyberexpress[.]com/gitlab-vulnerability-oj-parser-rce/]
- [hXXps://trust[.]cyble[.]com/]
- [hXXps://thecyberexpress[.]com/the-cyber-express-by-cyble-vulnerability-disclosure-policy/]