Unpatched GitLab Flaw: RCE Exploit Released for Critical Jupyter Notebook Vulnerability
Security researchers have released a working exploit for a critical remote code execution (RCE) vulnerability in **GitLab** that was quietly patched six weeks prior. The flaw, stemming from two memory corruption bugs in the **Oj** Ruby JSON parser, allows any authenticated user to execute commands as the `git` user on self-managed **GitLab** instances that haven't applied the update.
A working exploit for a significant **GitLab** remote code execution (RCE) vulnerability was published on July 24 by security researchers at **depthfirst**. This exploit targets a flaw that **GitLab** had patched six weeks earlier, on June 10, without classifying it as a security fix.

### The Vulnerability Chain
The exploit leverages two memory corruption bugs within **Oj**, a Ruby JSON parser largely implemented in C. **depthfirst** claims its system autonomously flagged these vulnerabilities, which researchers then chained manually.
Any authenticated user with push access to a project can trigger the exploit. The attack involves committing a specially crafted Jupyter notebook and then opening its commit diff. This action leaks a heap pointer, which an automated probe can use to locate libraries in memory. Two additional notebooks then deliver the payload, achieving RCE without administrator rights, CI/CD runner access, victim interaction, or access to other projects.
**GitLab's** `ipynbdiff` notebook renderer passes repository-controlled `.ipynb` JSON to `Oj::Parser.usual.parse` within a long-lived **Puma** worker. This allows attacker-controlled bytes to reach **Oj's** manually managed C memory within the application process.
One bug allows writing past a fixed 1,024-byte nesting stack, gaining control over the parser's `start` callback. The second bug truncates a 65,565-byte object key to 29 bytes in a signed 16-bit field, returning a live heap pointer that **GitLab** renders into the diff. This leak helps locate `libc`, and the write then directs the callback to `system()`.
### Impact and Affected Versions
The vulnerability affects all tiers of **GitLab CE/EE**, from Free through Ultimate. The **Oj** gem versions 3.13.0 to 3.17.1 are implicated, with the fix landing in 3.17.3.
| Component | Affected | First Fixed |
| :----------- | :------------------- | :----------- |
| GitLab CE/EE | 15.2.0 to 18.10.7 | 18.10.8 |
| GitLab CE/EE | 18.11.0 to 18.11.4 | 18.11.5 |
| GitLab CE/EE | 19.0.0 to 19.0.1 | 19.0.2 |
| Oj gem | 3.13.0 to 3.17.1 | 3.17.3 |
Notably, **GitLab** did not classify this fix as a security update. The **Oj** 3.17.3 bump was listed under bug fixes in the June 10 patch release, not in the security-fix table. This lack of classification, **The Hacker News** notes, meant no **CVE** or **CVSS** score was assigned, giving operators no reason to treat the update as urgent.

### Mitigation and Workarounds
Users are urged to upgrade to **GitLab** versions **18.10.8**, **18.11.5**, or **19.0.2**. No workaround is available for those unable to update immediately.
For **Helm** and **Operator** deployments, it's crucial to check the **GitLab** version within the **Webservice** image running **Puma**, rather than relying solely on chart or operator versions. Installations on versions 15.2 through 18.9 will not receive backports as these lines fall outside **GitLab's** security-maintained patch trains, necessitating an upgrade to a supported release.
Commands are executed as the `git` user, the account behind **Puma**. The extent of compromise depends on the installation's isolation, potentially exposing source code, **Rails** secrets, service credentials, CI/CD data, and internal services.
### Exploit Portability and Timeline
The public exploit is tailored for **GitLab 18.11.3** on x86-64. Porting it to other targets requires significant effort due to variations in gadget offsets, register states, and **jemalloc** behavior. **depthfirst** estimates memory searching on a fresh two-worker install takes five to ten minutes, extending to one to two hours on longer-running instances.
**depthfirst** reported the **Oj** bugs on May 21, with fixes merged by the maintainer on May 27, and **Oj 3.17.3** shipped on June 4. The **GitLab** chain was reported to **GitLab** on June 5, confirmed on June 8, and patched on June 10. **depthfirst** states they are unaware of in-the-wild exploitation, and **GitLab** independently reproduced the RCE.
**The Hacker News** has reached out to **GitLab** for clarification on the patch classification and potential **CVE** assignment, and to **depthfirst** regarding exploit portability. Responses are pending.