Depthfirst researcher Yuhang Wu found the underlying bugs the way a lot of serious vulnerabilities get found now, by pointing an automated analysis system at a widely used dependency and letting it work. The target was Oj, a high-performance native C-based JSON parser packaged as a Ruby gem and used across countless Ruby applications, GitLab included. The scan surfaced 18 prioritised issues, seven of them memory-safety bugs, two of which had sat unnoticed in Oj for 1,753 days before anyone worked out how to weaponise them.
An unchecked stack write and a leaked pointer
The two flaws that mattered were an unchecked nesting-stack write in Oj::Parser.usual.parse and an unsafe 16-bit key-length narrowing that leaked a heap pointer. Neither is exotic. Combined, they are enough to defeat GitLab’s memory protections from the inside. The exploit path itself needs nothing special: an ordinary authenticated user commits two crafted Jupyter notebooks to a project they can push to, then requests the diff between them. Reading that diff leaks a heap pointer; a second pair of notebooks locates the surrounding libraries in memory; two more fire the payload. No administrator rights, no CI runner access, no interaction from another user, and no access to a project the attacker does not already have permission to touch.
Reported quietly, fixed quietly, exploited loudly
Wu reported the core Oj bugs to the gem’s maintainers on 21 May 2026. A fix merged on 27 May, and Oj 3.17.3 shipped on 4 June. The GitLab-specific chain built on top of those bugs was reported on 5 June, confirmed on 8 June, and patched on 10 June across the 19.0.2, 18.11.5 and 18.10.8 releases. What did not happen is the part worth noting: GitLab’s release notes listed the Oj version bump under bug fixes, not in the security-fix table. No CVE was filed. No CVSS score exists. No mention of the notebook-diff chain appears anywhere in the public changelog. The only reason the wider world knows the real severity of what got patched is that Wu published working exploit code on 24 July, six weeks after the silent fix went out.
Who is exposed right now
The affected ranges are broad: GitLab CE and EE 15.2.0 through 18.10.7, 18.11.0 through 18.11.4, and 19.0.0 through 19.0.1. Anyone running a self-managed instance in those ranges who treated the June update as routine maintenance, rather than an urgent security patch, is still exposed today with a public exploit in circulation. GitLab.com’s SaaS offering is patched by GitLab directly, but self-managed instances are only as safe as the last update an admin actually applied, and this is exactly the kind of release that gets deprioritised when the changelog gives no indication anything security-relevant happened.
The uncomfortable pattern this points to
This is not the first time a fix has shipped quietly under a routine version bump while the real severity only became clear once a researcher went public. If your organisation runs self-managed GitLab, the immediate task is straightforward: confirm you are on 19.0.2, 18.11.5, 18.10.8 or later, right now, not on the next scheduled maintenance window. The harder task is process, not patching: dependency bumps buried in “bug fixes” sections do not show up in a changelog scan the way a CVE does, which means teams relying purely on security-advisory feeds to prioritise patching are missing exactly this class of risk.
If you want a second set of eyes on how your self-managed DevOps toolchain tracks and prioritises patches, including the ones that never get a CVE number, contact Excello Digital. We help European engineering teams build patch and dependency review processes that catch this kind of gap before an exploit goes public, not after.
