
Going depthfirst: Achieving GitLab RCE via Two Ruby Memory Corruption Vulnerabilities | depthfirst
Depthfirst's research describes an RCE chain against GitLab CE/EE (versions 15.2.0 through 18.10.7, 18.11.0 through 18.11.4, and 19.0.0 through 19.0.1) built from two memory-corruption bugs in the Oj Ruby JSON gem, reachable through the ipynbdiff notebook-rendering feature. It walks through an out-of-bounds write that corrupts a parser callback pointer, a heap-pointer disclosure used to defeat ASLR, and the gadget chain that reaches system() as the git user, plus nine additional Oj CVEs found during the same review.
I stopped the mechanism section because the exploitation walk-through is what the classifier flagged, and I won't reproduce it. Below is the defender-facing version, covering what the page says about exposure, fixes and limits.
What it is
Depthfirst reports an authenticated remote code execution chain against self-managed GitLab CE and EE. It combines two memory-safety bugs in the Oj Ruby JSON gem: an out-of-bounds write and a heap-pointer disclosure. Both date to Oj 3.13.0 (August 2021). Commands run as the git user, the account that runs GitLab's Puma workers. The page links a public PoC.
Preconditions / Affected
- The path is reachable through GitLab's notebook diff renderer, which calls
Oj::Parser.usual.parseon committed.ipynbfiles. GitLab made that change in 15.2.0 (July 2022). - Affected GitLab: 15.2.0 through 18.10.7, 18.11.0 through 18.11.4, and 19.0.0 through 19.0.1. A release is affected if it has the Oj notebook path and bundles Oj 3.13.0 through 3.17.1.
- GitLab 15.1 and earlier used
JSON.parsehere and are outside the chain. - The attacker needs a normal account that can push to a project and view a commit diff. The page says no admin rights, CI or runner access, victim interaction, or access to another user's project is needed.
- Possible impact, depending on deployment isolation: repository data, Rails secrets, service credentials and internal services reachable by the application.
What to do
- Upgrade to GitLab 19.0.2, 18.11.5 or 18.10.8 (released June 10, 2026), or a later supported patch release. These bundle Oj 3.17.3, the first gem with both fixes.
- Releases 15.2 through 18.9 got no backports. Those installs must move to a supported fixed release.
- For Helm and Operator installs, the first fixed charts under default mappings are 9.10.8, 9.11.6 and 10.0.2. The GitLab version in the Webservice image running Puma is authoritative, and image overrides take precedence.
- For release candidates, downstream packages and forks, check the two source conditions (the Oj notebook path and the Oj version) rather than the version label.
- GitLab.com was already patched, and Dedicated customers did not need to act.
- The page gives no detection guidance.
Other Oj advisories
The same review produced nine published Oj CVEs: CVE-2026-54502 (stack overflow in Oj.dump with a large indent), CVE-2026-54896 (heap overflow in exception serialization), CVE-2026-54897, 54898, 54899, 54901 and 54902 (use-after-free bugs), CVE-2026-54900 (negative-size memcpy in create_id handling), and CVE-2026-54903 (integer overflow on JSON strings over 2 GiB). Other Ruby apps that use Oj should check their gem version.
Caveats
- The demonstrated exploit depends on build details of the profiled GitLab 18.11.3 Omnibus image: allocator behavior, gadget offsets and library layout. The two Oj bugs themselves span all the affected releases.
- The page reports a roughly 5 to 10 minute address search on a fresh two-worker setup. For mature workers it extrapolates 1 to 2 hours.
- Timeline: reported to Oj on May 21, 2026, Oj 3.17.3 published June 4, GitLab confirmed June 8, and the report was resolved July 17.
Organisations named here
- heap pointer disclosure
- out-of-bounds write
CVEs named here
- CVE-2026-54502
- CVE-2026-54896
- CVE-2026-54897
- CVE-2026-54898
- CVE-2026-54899
- CVE-2026-54900
- CVE-2026-54901
- CVE-2026-54902
- CVE-2026-54903
Technologies named here
- GitLab.com
- GitLab
- RubyGems
- Ruby
- depthfirst
- Gitaly
- GitLab 15.1 and earlier: not affected, used JSON.parse rather than Oj in the notebook path
- GitLab CE
- GitLab Helm charts: affected prior to first fixed charts 9.10.8, 9.11.6, and 10.0.2
- ipynbdiff
- jemalloc
- Jupyter
- Oj
- Oj Ruby gem versions 3.13.0 through 3.17.1 (vulnerable parser merged August 8, 2021; analysis performed against Oj 3.16.16)
- Puma
- Workhorse
Techniques named here
- ASLR bypass
- Use-after-free
- Integer Overflow
- Allocator-assisted overlapping object write (heap grooming via realloc and object reuse)
- Heap pointer disclosure via integer truncation (narrowing of key length to int16_t)
- Out-of-bounds write via unchecked array/object nesting depth
- Remote code execution via Jupyter notebook diff rendering (user-controlled JSON reaching native parser)
Related in AppSec
Flowise MCP Security Bypass Enables RCE
Inside an Oracle Database SQL Injection Attack | Huntress
OASIS
